<!DOCTYPE html>
<html>
<head lang="zh">
	<meta charset="UTF-8">
	<link rel="stylesheet" href="css/base.css">
	<title>HTML5权威指南</title>
</head>
<body>
<section class="content">
	<h1>第一部分 开篇</h1>

	<p>用五章说明如何着手HTML5开发，介绍HTMLCSS和JavaScript。</p>

	<article>
		<h1>第1章 HTML5背景知识</h1>

		<p>HTML5的一大改进就是着力让浏览器处理那些原来要使用Flash才能实现的富内容。为了文档的自动化处理，应当加强语言档结构语义化，使表现和内容分离。当前真正的革新不是来自W3C，而是浏览器和插件。</p>

		<p>HTML5核心规范宝义标记内容的元素，并明确其含义：CSS用于控制内容呈现效果：JavaScript则用来操纵文档内容及用户操作，有些HTML5的新增元素必须要用JavaScript来操作。</p>

		<p>学习HTML5新特性最直接的方法是去<a href="http://www.w3.org">W3C</a>网站。</p>
	</article>
	<article>
		<h1>第2章 准备工作</h1>

		<p><a href="http://nodejs.org">node.js</a>用来编写服务器端的JavaScript脚本。</p>
	</article>
	<article>
		<h1>第3章 初探HTML</h1>

		<p>元素不区分大小写，但是近年常见的风格是全小写，这与CSS的要求是一致的。布尔属性有三种表示方式，比如：input … disabled
			/input…disabled=""/input…disabled="disabled"，这三种用法都可以。HTML5允许使用自定义属性，以data-为前缀。要记住HTML文档可能被其它终端处理，因此要保持良好的结构。</p>

		<p>使用accesskey属性可以为input元素添加访问快捷键，使用Alt +
			快捷键直接访问。JavaScript可以通过getElementByClassName来访问具有此类属性的元素。contenteditable属性，是HTML5新增加的，它的用途是让用户能修改页面上的内容（比如p元素，这些内容在以前是不能编辑的）。id属性用于标识元素，可以用于样式表，JavaScript和页面的导航。</p>

		<p>可以用lang属性指定元素使用的语言，可用的语言代码格式见<a href="http://tools.ietf.org/homl/bcp47">http://tools.ietf.org/html/bcp47</a>。title属性定义了当鼠标移到元素上时的提示消息。
		</p>

		<p>元素分为三大类：元数据元素（metadata element)-构建文档基本结构，流元素(flow element)-确定元素合法的父元素和子元素范围，短语元素(phrasing
			element)-同上，是流元素的子集。有些元素无法归入上面三类，比如li元素，作为不同元素的子元素时，表示不同的含义。</p>

		<p>常用的HTML实体引用：&lt; &gt; &amp &euro; &pound; &sect; &copy; &reg; &trade;</p>

		<p>全局属性：用来配置所有元素共有的行为，可以用在任何元素上，不过不一定会带来有意义或有用的行为改为。</p>
		<ul>
			<li>accesskey：设定快捷键，通过alt+字母访问，但有些浏览器不支持。见下面的form示例中的name和password，设置快捷键分别为n和p。</li>
			<li class="otherclass">
				class：用来为元素归类，常用于CSS或方便找到文档中的某一类元素(比如本行用JavaScript来修改外观）。一个元素可以归入多个类别，只需用空格分隔即可。注意，这类直接执行的脚本需要在元素后面定义。
			</li>
			<li contenteditable="true">contenteditable：HTML5新增属性，让用户能修改元素内容，比如这一行就可以修改。</li>
			<li>contextmenu：为元素设置右键菜单，当前还没有浏览器支持。</li>
			<li dir="rtl">dir：用于定义文字显示方向。其值有两个ltr和rtl分别表示从左向右和从右向左。比如这一行，定义为从右向左。其实看起来不是那么回事，好在这个也不会有什么用。</li>
			<li>draggable：HTML5新增，用于支持拖放操作的方式之一，表示元素是否可被拖放。</li>
			<li>dropzone：HTML5新增，用于支持拖放操作的方式之一，与draggable搭配使用。</li>
			<li><span id="toggle">hidden：这是个布尔属性，用于隐藏元素。点击后面的toggle按钮，将使本行主字隐现。</span><em>布尔属性的赋值好象有变动，必须给出明确的值而不能以单个属性名表示。</em>
				<button onclick="toggleHidden()">Toggle</button>
			</li>
			<li>id：给元素分配一个唯一标识符，用于将样式应用到元素上或在JavaScript中选择元素（见toggle示例），还可用于在文档中导航。在CSS中或导航中引用id，只需前面加“#”即可。</li>
			<li>lang：用于说明元素内容使用的语言。它的值必须为有效的ISO语言代码，具体参照http://tools.ietf.org/html/bcp47。还可用于选
				择指定语言的内容，只显示用户所选语言的内容或对其应用样式。
			</li>
			<li>spellcheck：用来表明浏览器是否对元素内容进行拼写检查。，只在用户可编辑的元素上才有意义。它的值有两个true/false。检查方式取决于浏览器和用户操作系统和浏览器的语言设置。</li>
			<li style="background: grey; color: blue;">style：用于直接在元素上定义CSS样式，比如这一行。这种方式应尽量减少使用。</li>
			<li>tableindex：定义Tab键在各个可得到焦点的元素间的切换顺序。-1为不会被Tab键选中。</li>
			<li title="这是一个气泡提示信息">title：用于定义气泡提示信息。</li>
		</ul>
		<script type="text/javascript">
			var elems = document.getElementsByClassName("otherclass")
			for (i = 0; i < elems.length; i++) {
				var x = elems[i];
				x.style.border = "thin solid blue";
				x.style.backgroundColor = "yellow";
				x.style.color = "black";
			}
		</script>
		<form>
			Name:<input type="text" name="name" accesskey="n" title="快捷键为Alt+n"/>
			Password:<input type="password" name="password" accesskey="p" title="快捷键为Alt+p"/>
			<input type="submit" value="Login" accesskey="s" title="快捷键为Alt+s"/>
		</form>
	</article>
	<article>
		<h1>第4章 初探CSS</h1>

		<p>
			几个CSS属性：border定义边框样式，color设置元素的前景色，padding设置元素内容与边框之间的间距，text-decoration设置文字的装饰效果。在样式表文件中导入其它css文件需要使用@import语句，并且要放在样式表的顶端。但是浏览器处理@import语句的效率不及link元素，因此除非有必要，还是用多个link语句引入不同样式表为好。如果要在样式表中声明样式表的字符编码，使用@charset语句，比如：@charset
			"utf-8";这是唯一可以出现在@import语句之前的语句，如果不指定字符编码，浏览器会使用载入该样式表的HTML文档所声明的编码，如果HTML文档也没有声明，则默认使用UTF-8。如果样式出现冲突，则以样式表中在后面的权重大，可理解为后面的覆盖前面的。</p>

		<p>与元素外观相关的属性比如文字颜色、字体等可被子元素继承，与布局相关的属性不会被继承。也可以用inherit关键字指定元素继承父元素属性，比如：border:inherit;可以强行指定元素的边框继承其父元素。</p>

		<p>关于样式表中颜色的定义，参看<a href="./w3_color.html"> www.w3.org/TR/css3-color</a>。</p>

		<p>还可以用函数来选择颜色，比如：rgb(112, 128, 44)，以RGB模型来表示颜色，而rgba(112, 128, 144,
			0.4)最后的a表示透明度，0代表完全透明，1带表不透明。或者用HSL模型（色相hue，饱合度saturation和明度lightness）来表示，比如color:hsl(120, 120%,
			22%)，相应的hsla则在其后又加入了透明度值。</p>

		<p>在CSS中除了可以应用in英寸/cm厘米/mm毫米/pt磅（1/72英寸）/pc（12磅）等绝对单位长度外，更常用的是相对长度单位，比如em与元素字号挂钩，rem与根元素（即html）字号挂钩，px
			CSS的象素（假定分辨率为96dpi），以及百分比用%来表示。</p>

		<p>px虽然是相对长度单位，但是浏览器实际上是以绝对长度来处理的，1象素大约等于英寸/96。现在大部分浏览器已经支持在CSS中使用数学运算，方法是calc(运算式)，如果要支持老浏览器请慎用。</p>

		<p>角度，数字后面跟deg即可，比如360度表示为360deg，这个IE11现在都不支持，因此一些旋转效果不能在IE中显示。时间，以s表示秒，ms表示毫秒。</p>

		<p>一个名为<a href="http://lesscss.org/">LESS</a>的工具可以用来扩展CSS，它使用JavaScript对CSS予以改进。另外，就是选择一些好用的CSS框架。</p>
	</article>
	<article>
		<h1>第4章 初探JavaScript</h1>

		<p>JavaScript大小写敏感，且不支持函数重载，如果有多个同名函数，那么后面的将覆盖前面的。没有块作用域，只有函数作用域，定义变量使用var，如果不用var将默认为全局变量。</p>

		<p>可以用new Object()定义一个对象，然后添加属性和方法。比如：</p>
	<pre>
		var myData = new Object();
		myData.name = 'Adam';	//和变量一样直接定义对象属性，不需要事件声明，而且也没有声明的方法
		myData.weather = 'sunny';
		myData.printMessage = function(){……};
	</pre>
		<p>也可以象下面这样：</p>
	<pre>
		var myData = {
			name: 'Adam',
			weather: 'sunny',
			printMessage: function() {
				document.writeln('Hello ' + this.name + '. ');
				document.writeln('Today is ' + this.weather + '.');
			}
		};
	</pre>
		<p>使用for...in循环可以遍历对象属性，比如：for(var prop in
			myData)，这样会对myData对象的每个属性执行一次，每次都将属性名称赋值给prop变量，这样就可以通过myData[prop]来调用每个对属性的值了。</p>

		<p>要删除对象属性使用delete关键字，比如delete myData.name;，判断对象是否具有某个属性，使用in关键字，比如：var hasName = 'name' in
			myData;。检测JavaScript变量为null或是undefined只需用！操作符即可，在相等运算符下null==undefined的值是true。比较流行的JavaScript库是jQuery。</p>
	</article>
</section>
<section class="content">
	<h1>第二部分 HTML元素</h1>

	<p>这一部分介绍HTML元素,包括HTML5新增或有所改动的元素</p>
	<article>
		<h1>第6章 HTML5元素背景知识</h1>

		<p>
			着重于文档语义化，HTML元素负责文档的内容和结构，使表现与内容分离。比如，article用于表示独立篇的内容，而figure元素表示的是图片。避免使用那些具有呈现总味的元素，比如b,i等。如果找不到合适的元素表示语义可使用span或div，
			不要修改元素原有意图。</p>

		<p>不要误用元素，并要保持一致。</p>
	</article>
	<article>
		<h1>第7章 创建HTML文档</h1>

		<p>HTML文档的元数据和文档信息包含在head中，文档内容在body中</p>

		<p>每个文档都应包含一个base元素，用来定义基准URL，比如&lt;base href="http://titan/listings/"
			/&gt;，这样做的好处是使用相对路径时避免出错，而且不要忘记路径后面的斜杠。</p>

		<p>在meta中可以使用keywords关键字来描述文档的主要内容（一些以逗号分割的关键字），并搜索引擎检索，但是当前搜索引擎对其这个关键字已经不重视了，要做推广需要看搜索引擎的规则，</p>

		<p>服务器对网页的每条响应都包含一组向浏览器说明其内容的字段，meta元素可用来替换其中三种标头字段。比如，&lt;meta http-equiv="refresh" content="5"&gt;。下面是http-equiv允许使用的三个值：</p>
		<dl>
			<dt>refresh</dt>
			<dd>以秒为单位指定一个时间间隔，让服务器以指定间隔重新载入当前页，也可另行指定一个URL让服务器载入，比如：http-equiv="refresh" content=5;
				http://www.apress.com"。
			</dd>
			<dt>default-style</dt>
			<dd>指定页面优先使用的样式表，对应的content属性值应当与同一文档中某个style元素或link元素的title属性相同。（不是很有用）</dd>
			<dt>content-type</dt>
			<dd>这是另一种声明HTML所用字符编码的方法，比如：http-equiv="content-type" content="text/html charset=utf-8"。这个在发送邮件时会有用。</dd>
		</dl>
		<p>
			media语句（在CSS文件中前面要加@）可以定义样式表适用的设备和特性条件，除了可以用AND来组合特性外，不可以使用NOT或逗号（表示OR），几乎用于media的所有特性都可以加min-或max前缀来定义，可用特性如下表：</p>
		<table>
			<caption>可用样式表的media特性</caption>
			<thead>
			<tr>
				<th>特性</th>
				<th>说明</th>
				<th>示例</th>
			</tr>
			</thead>
			<tbody>
			<tr>
				<td>width | height</td>
				<td>指定浏览器窗口的宽度和高度，单位是px，代表像素</td>
				<td>width:200px</td>
			</tr>
			<tr>
				<td>device-width | device-height</td>
				<td>指定整个设备（而不仅仅是浏览器窗口）的宽度和高度，单位是px</td>
				<td>min-device-height:200px</td>
			</tr>
			<tr>
				<td>resolution</td>
				<td>指定设备的像素密度。单位是dpi（点/英寸）或dpcm（点/厘米）</td>
				<td>max-resolution:600dpi</td>
			</tr>
			<tr>
				<td>orientation</td>
				<td>指定设备较长边的朝向。支持的值有portrait和landscape，该特性没有限定词，不能用min-或max-前缀。这是当然的，只是纵向或横向</td>
				<td>orientation:portrait</td>
			</tr>
			<tr>
				<td>aspect-ratio | device-aspect-ratio</td>
				<td>指定浏览器窗口或设备的像素宽高比。其值表示为像素贡度与像素高度的比值</td>
				<td>min-aspect-ratio:16/9</td>
			</tr>
			<tr>
				<td>color | monochrome</td>
				<td>指定颜色或黑白设备上每个像素点用的二进制位数</td>
				<td>min-monochrome:2</td>
			</tr>
			<tr>
				<td>color-index</td>
				<td>指定设备所能显示的颜色数目</td>
				<td>max-color-index:256</td>
			</tr>
			<tr>
				<td>scan</td>
				<td>指定电视的扫描模式。支持的值有progressive和interlace。逐行或隔行扫描，当然也不能用前缀</td>
				<td>scan:interlace</td>
			</tr>
			<tr>
				<td>grid</td>
				<td>指定设备的类型。网格型设备使用固定的网格显示内容，例如基于字符的终端和单行显示的寻呼机，LED屏应当也属此类。支持的值有0和1（1代表网格型设备），当然也不用加前缀。</td>
				<td>grid:0</td>
			</tr>
			</tbody>
		</table>
		<p>
			link元素用来指定HTML文档和外部资源之间建立联系。用href定义资源的URL，hreflang说明资源使用的语言，media定义关联的设备，rel说明文档与所关联资源的关系类型，size指定图标大小，type指定所关联资源的MIME类型，比如：text/css、image/x-icon。为rel属性设定的值决定了浏览器对待link元素的方式，如下：</p>
		<dl>
			<dt>alternate</dt>
			<dd>链接到文档的替代文本，比如另一种语言的译本</dd>
			<dt>author</dt>
			<dd>链接到文档的作者</dd>
			<dt>help</dt>
			<dd>链接到当前文档的说明文档</dd>
			<dt>icon</dt>
			<dd>指定图标资源，为页面定义图标，即在浏览器的标签或收藏夹内显示的网站小图标，如果此图标位于/favicon.ico就不需要使用link元素定义，浏览器会默认加载。比如：ink rel="shortcut
				icon" href="test.ico" type="image/x-icon"
			</dd>
			<dt>license</dt>
			<dd>链接到当前文档的相关许可证</dd>
			<dt>pingback</dt>
			<dd>指定一个回探（pingback）服务器。从其他网站链接到博客的时候它能自动得到通知</dd>
			<dt>prefetch</dt>
			<dd>预先获取一个浏览器很快会用到的资源，这样可以在点击到这个资源的链接时立即响应。比如：link rel="prefetch" href="/page2.html"</dd>
			<dt>stylesheet</dt>
			<dd>载入外部样式表</dd>
		</dl>
		<p>用script标记载入JavaScript脚本时一定不要用自闭合标记，而是要像这样&lt;script defer async src=“simple.js"&gt;&lt;/script&gt;。建议将JavsScript脚本放在文档最后，如果一定要在前面的话，可以在script中加入defer属性，让脚本在文档加载完后再执行，这和将JavaScript放在文档末尾是一样的。async属性则可以在浏览器载入脚本时继续解析文档的其它元素，默认浏览器在下载脚本时是暂这片进页面的。</p>
	</article>
	<article>
		<h1>第8章 标记文字</h1>

		<p>a元素target属性的几个值：_blank在新窗口打开，_parent在frameset中打开，_self（默认值）在当前窗口打开，_top在顶层窗口打开，&lt;frame&gt;在指定frame中打开。</p>

		<p>b元素、u元素以及small元素这种以外观为主的就不要用了，em元素示强调，i元素表示外文字汇或科技术语，s元素表示文字不再正确或准确（在文字上显示删除线），strong表示重要的文字。</p>

		<p>sub元素表示<sub>下标</sub>sup表示<sup>上标</sup>。q元素表示引用自其它文章的内容，它的cite属性指向被引用文章的链接。abbr元素表示缩写，它的title属性要说明该缩写代表的完整词语。
			dfn表示定义中的术语，它的title属性必须和定义的术语一样。cite元素表示引用作品的标题。</p>

		<p>ruby元素表示注音符号在文字的上方显示拼音，它要和rt和rp元素一起使用。rt元素用来表示注音符号，rp元素用来标记不支持注意符号特性的浏览器显示括号。比如：
			<ruby>魑
				<rp>(</rp>
				<rt>chi</rt>
				<rp>)</rp>
			</ruby>
			<ruby>魅
				<rp>(</rp>
				<rt>mei</rt>
				<rp>)</rp>
			</ruby>
		</p>
		<p>bdo元素，明确指定内容中文字的方向，它必须要加dir属性（可用的值有ltr和rtl）。比如：<bdo dir="rtl"> 这几个文字，就是倒着的。</bdo></p>

		<p>mark元素，用来突出显示某段文本。一般为
			<mark>黄底黑字</mark>
			。ins和del元素分别表示要在文档中
			<ins datetime="2015-4-11"> 添加</ins>
			和
			<del datetime="2015-4-11">删除</del>
			的文字，可用属性cite和datetime。
		</p>
		<p>time元素用来表示时间或日期，如果布尔属性pubdate存在，那么它表示的是整个HTML文档或离它最近的article元素的发布时间。比如这个：
			<time datetime="2015-4-11">April 27th</time>
			。这个元素并不显示，只是为了将来分析分档使用。
		</p>
	</article>
	<article>
		<h1>第9章 组织内容</h1>

		<p>本章用来介绍组织内容的元素，将文档内容分类，主要是流元素，比如段落、列表、图片等。div元素没有具体的含义，在找不到其他恰当的元素时可用这个元素为内容建立结构并使用id或class属性赋予其含义</p>

		<p>
			pre元素可以改变浏览器处理内容的方式，阻止合并空白字符，让源文档中的格式得以比如空格和换行保留。除非原始格式意义生大（比如源代码）除此之外不要使用这个元素，因为它消弱了用元素和样式来控制呈现结果的灵活性。它与code元素一起表示代码时很有用，比如：</p>
		<pre>
			<code>
				var fruits = ['apples', 'oranges', 'mangoes'];
				for (var i = 0; i < fruits.length; i++)
				{
				document.writeln('I like ' + fruits[i];
				}
			</code>
		</pre>
		<p>blockquote元素表示整片引自它处的内容，前面的q表示几句或一部分，这个表示大篇幅的引用，它的cite属性可用来注明来源。</p>

		<p>hr表示一个主题向另一个相关主题的转换。这个只是一个外观的习惯，与语义化结构不相干。</p>

		<p>ol元素表示有序列表，有start属性指定开始的编号，如果不定义，则从1开始。type属性定义编号样式（1-默认，十进制数；a-小写英文字母；A-大写英文字母；i-小写罗马数字；I-大写罗马数字）。</p>

		<p>ul表示无序列表，不再支持局部属性，全在样式表中定义。</p>

		<p>一个dt元素可以带多个dd元素，这样就可以为一个术语提供多个定义。</p>

		<p><em>生成自定义列表</em>结合CSS中的counter特性和<code>:before</code>选择器，可以用ul元素生成复杂的列表。第17章介绍。</p>

		<p>
			figure插图-一个独立的内容单元，除图片外还指图表或图示，可带标题用figcaption子元素来表示，而且figcaption元素必须是figure元素的第一个或是最后一个子元素。通常作为一个整体被文档引用，把它从文档主体中删除也不会影响文档的意思。</p>

		<p></p>
	</article>
	<article>
		<h1>第10章 文档分节</h1>

		<p>本章主要介绍文档结构元素，这是构成语义与结构分离的基础。</p>

		<p>
			文档中的标题尽量只用到第三级就好了，虽然可用的有六级。hgroup元素（HTML5新增）可以用来将几个标题作为一个整体处理，一个应用场景是主标题和副标题在一起，hgroup在标题体系中的级别取决于它的第一个子元素的标题级别，如果第一个子元素是h2，则此hgroup也是h2级。</p>

		<p>
			section元素，表示文档中的一节，用来包含那种应该列入文档大纲或目录中的内容，又或者一些片断。通常包括一个或多个段落与标题，但标题不是必须的。可以这样认为，如果作为一本书的话，封面和前言是一节，目录是一节，正文又是一节，因为此三者的页码是分别独立的。/</p>

		<p>
			header/footer表示一节的首部/尾部，也可以是body或article等的首部/尾部。header通常包含一个标题元素或hgroup元素，还可以包含该节的导航元素(nav)。footer通常包含该节的总结信息，作者介绍、版权信息、到相关内容的链接、徽标及免责声明等。</p>

		<p>nav元素表示文档中的一个区域，它包含着到其他页面或同一页面其他部分的链接。有些浏览器会对位于section内的标题元素做降低一级处理，有些不会。</p>

		<p>article元素代表HTML文档中一段独立成篇的内容，一篇博文或是一篇新的文章都可以用这个元素。使用方式可以<a href="listing-07.html">参考这个示例</a>。</p>

		<p>aside元素用来表示跟周边内容稍沾点边的内容，类似于书或杂志中的侧栏，不属于页面主体却有点关系，比如背景信息或相关文章的链接等。</p>

		<p>
			address元素用来表示article元素的联系信息，它提供的信息被视为是其父元素的，如果父元素是body则被认为是整个HTML文档的联系信息，他不能用来在文档中表示客户或用户的地址，如果有为用户或客户定义专用元素，那可将address用作其子元素以表示他们的联系方式。</p>

		<p>details元素在文档中生成一个区域，用户可以展开它以了解关于某个主题的更多详情，它通常包仿一个summary元素用来生成一个说明标签或标题。比如：</p>
		<details>
			<summary>这是一个details元素的标题</summary>
			<p>这里就是details元素的内容了，不过倒底要不要把所有文字都放进p标签里呢？不是所有浏览器都支持这个属性。现在好像只有chrome支持。要让它展开显示就要调用details元素的open属性。</p>

			<p>还是放在p元素里好些，不然真不好控制段落。</p>
		</details>
	</article>
	<article>
		<h1>第11章 表格元素</h1>

		<p>不要将表格用于布局页面!下面是一个完整的表格示例</p>
		<table>
			<tr>
				<th>复杂一点的</th>
				<th>加上th表头</th>
				<th>用粗体</th>
				<th>显示</th>
			</tr>
			<tr>
				<th>表示必须的三个基本元素</th>
				<td>table</td>
				<td>tr</td>
				<td>td</td>
			</tr>
			<tr>
				<th>th也可用于左侧第一列</th>
				<td colspan="3">如果要合并列,使用td的colspan属性</td>
			</tr>
		</table>
		<p>
			下面是加上完整表结构的一个表，使用colgroup可以定义列的呈现，如果在此元素中使用span属性可以定义跨越几个列，或者在使用它的col子元素来逐个定义列（当然col子元素中使用span属性也可以定义多列）。有点特殊的是它所影响的元素并不在它的里面定义因此，因此无法使用colgroup>td来影响单元格外观。</p>
		<table>
			<caption>这是一个表格的标题，有点只能有一个，虽然不必是第一个元素，但它总是显示在表格上方</caption>
			<colgroup id="colgroup1" style="background-color: #ff0000;">
				<col id="col1And2" span="2">
			</colgroup>
			<colgroup id="colgroup2" style="background-color: #9acd32" span="2"/>
			<thead style="background-color: #b8860b">
			<tr>
				<th>表头放在</th>
				<th>thead</th>
				<th>元素</th>
				<th>内</th>
			</tr>
			</thead>
			<tfoot>
			<tr>
				<th>在HTML5之前tfoot元素</th>
				<th>只能在thead后</th>
				<th>HTML5更灵活</th>
				<th>可放在tbody后面</th>
			</tr>
			</tfoot>
			<tbody>
			<tr>
				<th>表格内容</th>
				<td>放在</td>
				<td>tbody</td>
				<td>元素内</td>
			</tr>
			<tr>
				<th>th也可用于左侧第一列</th>
				<td colspan="3">如果要合并列,使用td的colspan属性</td>
			</tr>
			</tbody>
		</table>
		<p>
			colspan和rowspan属性应该用在占要占据的网格左上角那个单元格上，它所跨越的位置上的td或th省略即可。td和th还可以定义headers属性，使之于其它单元格（headers值为一个或多个其他单元格的id)关联。</p>
	</article>
	<article>
		<h1>第12章 表单</h1>

		<p>HTML5的表单系统已彻底改造过，已可以跟上应用的步伐。基本的表单有三个元素form/input/button。</p>

		<p>form元素不能嵌套，input元素用来收集输入的数据，button有多种用途，最普通的是告诉浏览器把用户输入的数据提交给服务器。</p>

		<p>
			form元素的action属性定义提交表单时将数据发送到什么地方，如果不定义这一属性，则会将数据发送到调用这个HTML文档的URL。method属性定义了将表单属性发送到服务器的HTTP方法GET（默认，明文不安全）或POST。</p>

		<p>form元素的enctype属性指定了流畅览器对发送给服务器的数据采取的编码方式：application/x-www-form-url-urlencoded
			这是默认方式，不能用来将文件上传到服务器：multipart/form-data 这种方式用来将文件上传到服务器：text/plain 这种方式因浏览器而异，结果难料不要使用。</p>

		<p>
			form元素默认autocomplete属性为on，即开启表单元素的自动填写功能，如果不要这个功能可设置autocomplete="off"，也可以单独设置表单元素的autocomplete属性。可以设置form的target属性，来指定反馈信息的显示位置，默认为_self。</p>

		<p>如果要在DOM中引用form元素，需要设置form的name属性。</p>

		<p>
			使用label元素为表单元素添加说明，一般可以将input元素作为label的子元素，也可以分开定义，使用label的for属性指向input元素的id属性以为二者建立关联。如果要让某个input元素自动获得输入焦点，可定义它的autofocus属性。对于复杂的表单，可能要将一些元素组织在一起，为此，可使用fieldset元素，要为fieldset元素添加说明，可使用legend元素，通过设置fieldset元素的disabled属性可以禁用整组元素。一个示例如下：</p>

		<p>button元素有三种用途，通过type属性来设定：submit 默认，表示提交表单：reset
			重置表单：button没有具体意义，用于JavaScript脚本执行特殊定操作。当type被设置为submit时，可用以下属性：</p>
		<ul>
			<li>form 指定按钮关联的表单</li>
			<li>formaction 覆盖form元素的action属性，指定要提交到的URL</li>
			<li>formenctype 覆盖form元素的enctype属性</li>
			<li>formmethod 覆盖form元素的method属性</li>
			<li>formnovalidate 覆盖form元素的novalidate属性，表明是否应执行客户端数据有效性检查</li>
		</ul>
		<form id="voteform" name="userinfor" method="post" action="index.html">
			<fieldset>
				<legend>Enter Your Details</legend>
				<p><label for="name">Name<input id="name"/> </label></p>

				<p><label for="city">City<input id="city"/> </label></p>
			</fieldset>
			<fieldset>
				<legend>Vote For Your Three Favorite Fruits</legend>
				<p><label for="fave1">#1<input id="fave1"/> </label></p>

				<p><label for="fave2">#2<input id="fave2"/> </label></p>

				<p><label for="fave3">#3<input id="fave3"/> </label></p>
			</fieldset>
			<button>Submit Vote</button>
			<button type="reset">Reset</button>
		</form>
		<p>在HTML5中，表单元素不必放于form元素内，如果要将form元素外的元素应用于某个表单，只需为表单定义id属性，并将元素的form属性值设置为表单的id值即可与表单建立关联。</p>
		<button form="voteform">这个按钮在form元素之外，但一样作用于上面的form元素</button>
	</article>
	<article>
		<h1>第13章 定制input元素</h1>

		<p>
			要配置input元素需要用到其type属性，共23个不同的值，配合type不同值又有几个额外属性，共计30个属性可用。定义required属性表明用户必须输入一个值，否则无法通过验证。下面是可用的type属性值及应用方法：</p>
		<ul>
			<li>text
				显示为单行文本框，这是input元素的默认属性，如果不定义type属性，则表示为text。可用pattern定义一个正则表达式来限定用户可用的字符。size定义可显示的字符长度，maxlength定义最多可接受的字符数。value定义默认值，placeholder定义提示文字告诉用户接受什么样类型的数据，但是只能在value为空时显示。配合datalist元素，可使用list属性为文本预置一个列表。readonly（这样的值不可编辑但会被提交）和disabled（这样的值不会被提交）属性用来生成不能编辑的文本框。
			</li>
			<label for="text">这是一个文本<input type="text" id="text" size="30" maxlength="20" value=""
										   placeholder="请输入任何字符，但不要超过20个"/> </label>
			<label for="fruits">这是一个预置列表项的文本框<input type="text" id="fruits" list="fruitlist"/>在输入列表项中包含的相关字符时会显示可用列表项。
			</label>
			<datalist id="fruitlist">
				<option value="Apples" label="Lovely Apples"/>
				<!-- 注意，如果要用label提示的话，尽量说明值与提示的关系，这两者是不同的，真正自动录入的是用value定义的值，而不是label的值 -->
				<option value="Oranges">Refreshing Oranges</option>
				<!-- 也可以用这种方法，元素内的内容作用与label属性相同 -->
				<option value="Cherries"/>
			</datalist>
			<li>password 用来接受用户密码，可用pattern定义一个正则表达式来限定用户可用的字符</li>
			<li>button/submit/reset 这三种用类型可生成按钮，用法与button元素相同。因为有些旧浏览器不能识别button元素，所以会用这种方式替代。</li>
			<li>number
				生成只接受数值的输入框，还带有上下调数的按钮(IE11不支持）。它也支持datalist属性，用法同上，只是value属性只能是数字（可以是小数）。min/max属性定义接受的最小/大值。required表示必须输入一个值，readonly设为只读，step指定上下箭头调整的步长。<input
						type="number"/></li>
			<li>range 属性用法与number相同，只是，用户只能从它事件规定的范转上内获得一个值，也就是说它必须定义min和max属性。-10<input type="range" min="-10"
																						 value="-9" max="10" step="1"/>10
			</li>
			<li>checkbox checked表示复选框被选中，value是被选中时的值required表示必须勾选。只处于选中状态时的值才会提交。</li>
			<li>radio 用法类似checkbox但是只能多选一。同样，如果没有选择其中的选项则值不会被提交。</li>
			<li>email/tel/url
				它们都支持list/maxlength/pattern/palaceholoder/readonly/required/size/value属性，email还支持multiple属性允许接受多个电子邮件地址。浏览器会在用户提交时检查数据格式。
			</li>
			<li>datetime/datetime-local/date/month/time/week
				日期和时间包括时区/本地日期和时间/本地日期/本地年月/本地时间/本地星期。日期和时间用T分隔，比如2015-04-20T22:46。
			</li>
			<li>color 获得颜色值，它的值用#后加六位16进制数表示。比如：<input type="color" value="#FFCC99"/></li>
			<li>search 生成一个单行文本框,让用户输入搜索词，它实际上什么也不能做，只是规划了这样一个功能，与text型的input元素是一样的。</li>
			<li>hidden 生成一个隐藏数据项</li>
			<li>image 生成图像按钮，点击它可以提交表单。除了可以使用button元素关于提交的属性外，还可有height/width/src三个属性用于定义按钮图片，alt属性提供说明文字。</li>
			<li>file 上传文件。表单类型（enctype)为multipart/form-data的时候才能上传文件。accept属性定义接受的MIME类型（参见<a
					href="http://tools.ietf.org/html/rfc2046">RFC 2046</a>）。multiple属性可以一次上传多个文件。required必须提供一个值，否则无法通过输入验证。
			</li>
		</ul>
	</article>
	<article>
		<header><h1>第14章 其他表单元素及输入验证</h1></header>
		<p>
			select元素用来生成选项列表，如果设置了multiple属性也可以一次多选。选项用option定义，如果是多选，可以用size定义一次显示的option选项数（行数）。使用optgroup可以为select的列表示分组。比如：</p>
		<label for="fave3">
			Favorite Fruit:
			<select id="fave3">
				<optgroup label="TopChoices">
					<option value="apples">Apples</option>
					<option value="oranges">Oranges</option>
				</optgroup>
				<optgroup label="Others">
					<option value="cherries" label="Cherries">Cherries</option>
					<option value="pears">Pears</option>
				</optgroup>
			</select>
		</label>

		<p>textarea 元素可输入多行文本，用rows和cols属性来设置大小，wrap属性有两个值hard（会在cols定义的列数插入换行符）和soft用来控制用户输入的文字中插入换行符的方式。</p>

		<p>output 表示计算结果，比如：</p>

		<form onsubmit="return false" output="res.value = quantity.valueAsNumber * price.valueAsNumber">
			<fieldset>
				<legend>输出计算结果output</legend>
				<input type="number" placeholder="Quantity" id="quantity" name="quantity"/>*
				<input type="number" placeholder="Price" id="price" name="price"/>=
				<output for="quantity price" name="res"/>
			</fieldset>
		</form>
		<p>keygen 生成公开/私有密钥对。提交表单时该元素会生成一对新的密钥，公钥发送给服务器，私钥由浏览器保留并存入用户的密钥仓库。但是浏览器对这个元素的支持好像不怎么样，用到再说。</p>

		<p>required 属性可以确保用户提供了一个值，但无法判断值是否真的有效，因此要彻底验证还是要通过JavaScript及服务器程序。min和max属性可以将用户输入的值限定在一个范围内。</p>

		<p>pattern 属性可以用来确保输入的值与一个正则表达式匹配，这个可以作为required属性的补充，进一步验证有效性。与email或url类型的input元素配合使用来验证有效性也是个不错的选择。</p>

		<p>要想取消表单输入验证，为form表单设置novalidate属性即可，也可以单独为提交表单的button元素或input元素设置novalidate属性。</p>
	</article>
	<article>
		<h1>第15章 嵌入内容</h1>

		<p>img
			元素用来嵌入图像，必须要设置它的src（图像文件URL）、alt（不能显示图像时的替代文字）、width和height（如果不设置宽高则会使图像在文档加载完成后才显示，这两个属性告诉浏览器图像的尺寸，不要用这两个属性来缩放图像。</p>

		<p>
			将a元素的内容设置为img元素时，就可以使用img元素的ismap属性创建一个服务器分区响应图。如果点击的位置是离图像顶部4像素左边缘10像素，浏览器就会导航到以下地址:http://url/?10,4，如果省略ismap属性则不会生成点击的坐标。下面的这段JavaScript脚本可以用业显示点击位置的坐标：</p>
		<pre>
			var coords = window.location.href.split('?')[1].split(',');
			document.write('The X-coordinate is ' + coords[0]);
			document.write('The Y-coordinate is ' + coords[1]);
		</pre>
		<p>
			map元素包含一个或多个area元素，它们各自代表了图像上一个可被点击的区域。使用img元素的usemap属性以#引用map元素的name属性即可将这些area区域映射到img元素的图像上。area元素除了可以像定义a元素的链接特性外，还可以配合shape属性与coords属性定义区域形状，比如：</p>
		<ul>
			<li>rect 矩形区域，这时coords属性必须由四个用逗号分隔的整数且成，说明矩形左上角和右下角的坐标</li>
			<li>circle 圆形区域，它的coords属性必须由三个整数组成，分别表示圆心到图形左上角的距离和圆半径</li>
			<li>poly 代表多边形，coords属性必须至少包售六个用逗号分隔的整数，每一对数字代表多边形的一个顶点</li>
			<li>default 表示默认区域，即覆盖整张图片这时不需要使用coords属性</li>
		</ul>
		<p>比如像下面这像：</p>
		<pre>
		&lt;img src="sim.png" usemap="#mymap" alt"A simple example" /&gt;

		&lt;map name="mymap"&gt;
			&lt;area href="..." shape="rect" coords="3,5,68,62" alt="...."&gt;
			&lt;area href="..." shape="circle" coords="70,80,30" alt="..."&gt;
			&lt;area href="..." shape="defautl" alt="..."&gt;
		</pre>
		<p>使用map来定义图像区域时就可以不用a元素来显式创建超链接了。</p>

		<p>iframe元素用来在一个HTML文档中嵌入<a href="10-3.html" target="myframe">另一个</a>，比如像下面这样：</p>
		<iframe name="myframe" width="300" height="100" src="listing-07.html"></iframe>
		<p>
			iframe元素可以使用seamless属性，使其内容像是所在文档的一部分，以及sandbox属性禁用被嵌入文档的脚本、表单、插件及指向其他浏览器上下文的链接，如果要启用某些值，只需为sandbox属性赋以下可用值即可，如果将其用作布尔属性则禁用所有。</p>

		<p>sandbox可接受的值</p>
		<ul>
			<li>allow-forms 启用表单</li>
			<li>allow-scripts 启用脚本</li>
			<li>allow-top-navigation 允许链接指向顶层的浏览上下文，这样就能用另一个文档替换当前整个文档创建建一个新的标签和窗口</li>
			<li>allow-same-origin 允许iframe里的内容被视为与文档其余部分拥有同一个来源位置</li>
		</ul>
		<p>embed元素用来添加插件支持，也可以用来嵌入流览器能直接处理的内容，比如图像。emb元素使用示例如下：</p>
		&lt;embed src="要引用的媒体内容的URL" type="application/x-shockwave-flash这是MIME类型示例" width="560" height="349"
		allowfullscreen="true" /&gt;
		<p>object元素和embed元素一样，但工作方式稍有不同，且带有一些额外功能。比如上面的示例用object元素应当这样写（注意，它是以data元素来定义内容的地址）：</p>
		<pre>
		&lt;object data="要引用的媒体内容的URL" type="application/x-shockwave-flash这是MIME类型示例" width="560" height="349"&gt;
			allowfullscreen="true" /&gt;
			&lt;param name="allowFullScreen" value="true" /&gt;
			<b>sorry!</b> We can't display this content!
		&lt;/object&gt;
		</pre>
		<p>object元素的一大优点是，可以指定备用内容。如果内容链接失败或失效就会显示object元素里面的内容，比如上例中的，<b>sorry!</b> We can't display this
			content!还可以用object元素取代img以及其他功能，但是浏览器支持不好，另外，也很罗索，还是算了。</p>

		<p>progress元素 进度条，用来表示某项任务逐渐完成的过程。它有三个属性可用，value定义当前进度，它的值位于0和max之间，当max被省略时，范围是0到，用浮点数来表示进度。</p>

		<p>meter元素
			显示某个范围内所有可能值的一个。它的显示可分为三部分，过低、过高和最佳。用low属性设定一个值，在它之下所有值都是过低，high属性设定一个值，在它之上所有值都被设为过高，而optimum属性则指定了最佳的值。</p>
	</article>
	<h1>第三部分 CSS</h1>
	<article>
		<h1>第16章 理解CSS</h1>

		<p>在模块定义还不稳定的阶段，浏览器会采用厂商前缀实现某个特性。常的的浏览器厂商前缀如下：</p>
		<ul>
			<li>chrome safari -webkit-</li>
			<li>opera -o-</li>
			<li>firefox -moz-</li>
			<li>Internet Explorer -ms-</li>
		</ul>
		<p>
			CSS的一个基本概念是盒模型，即每个可见元素在页面中占据一个矩形区域，这个区域就是元素的盒子（box）由四部分组成，即外边距margin（边框与页面上其它元素之间的间距），内边距padding（内容与边框间的空间），边框border和内容，其中内容和边框是可见的，如下图：</p>
		<img src="images/box.bmp" alt="CSS的盒模型示意图"/>
		<em>这一章全面简介了CSS的选择器和各种属性，可作为参考手册。后续章节逐步介绍</em>
	</article>
	<article>
		<h1>第17章 使用CSS选择器（第I部分）</h1>

		<p>
			类选择符，根据元素的class属性选择，有两种表现形式：一是使用.类名，一是使用通用选择器即*.类名。类选择器的具体程度还可以更高，即指定类匹配的元素类型，比如：p.class2。如果想选择属于多个类的元素，可在元素类型后用.分隔多个类名，比如：span.class1.class2</p>

		<p>id选择符的两种表现形式同类选择符，即#id或*.#id。</p>

		<p>属性选择器：基于属性的不同方面匹配属性。格式：[条件]或用元素类型['条件']。条件说明如下（attr表示属性名）：</p>
		<ul>
			<li>[attr] 选择拥有attr属性的元素，忽略属性值</li>
			<li>[attr="val"] 选择拥有attr属性并且值为val的元素</li>
			<li>[attr^="val"] 选择拥有attr属性并且值以字符串val打头的元素</li>
			<li>[attr$="val"] 选择拥有attr属性并且值以字符串val结尾的元素</li>
			<li>[attr*="val"] 选择拥有attr属性并且属性值包含字符串val的元素</li>
			<li>[attr~="val"] 选择拥有attr属性并且属性具有多个值，其中一个值为字符串val的元素，比如：class="class1
				class2"这样的元素就可以用[class~="class2"]或[class~="class1"]来选择
			</li>
			<li>[attr|="val"] 选择拥有attr属性并且属性值为连字符-分隔的多个值，其中第一个为字符串val的元素，比如：lang=en-us就可以用[lang|="en"]来选择。</li>
		</ul>
		<p>复合选择器，组合使用不同的选择器可以减少代码或匹配更特定的元素。使用方式如下：</p>
		<ul>
			<li>并集选择器 由逗号,分隔的多个选择器列表，可以将样式匹配到列表中的所有元素，比如，可以同时这样定义：a, [lang|="en"]{...}</li>
			<li>后代选择器 用于选择包含在其它元素中的元素，只需要用空格分隔，它会匹配第一个选择器元素中的元素而不仅是直接子元素。比如：p span
				匹配的是p元素内的所有span元素，无论有多少级嵌套，只要是在p元素中的span都匹配
			</li>
			<li>选择子元素 它与后代选择器很象，但只匹配直接子元素。使用方式是用大于号>分隔选择符。比如p>span，它只匹配p元素下的span元素即直接子元素。span元素内再嵌套span则会不匹配，<a
					href="cssexapmle.html">示例</a>。这种方式实际上是明确定义了元素的层级，比如：body>*>span, tr>th
			</li>
			<li>选择兄弟元素 使有兄弟选择符可选择紧跟在某元素之后的元素。使用方式是用+分隔选择符。比如p+a，它匹配的是紧跟着p元素的a元素。还有普通兄弟选择符~，比如p~a，它匹配的是p后面的所有a元素不用紧跟着。
			</li>
		</ul>
		<p>伪选择器，并非直接对应HTML文档定义的元素，分为伪元素（即实际上不存在的元素，只在CSS中定义，用法类似于元素）和伪类。下面是常用的伪元素：</p>
		<ul>
			<li>::first-line
				匹配文本块的首行。如果不加限定，那么将定义所有块级元素的首行。比如要设定p元素的首行，只需要定义p::first-line即可。虽然这类选择器有两个冒号，但浏览器只认为有一个，用两个是为了向后兼容。
			</li>
			<li>::first-letter 匹配文本块的首字母。</li>
			<li>:before和:after选择器
				它们会生成内容并将其插入文档，通过设置其content属性来定义要插入的内容，属性值要用双引号。:before和:after选择器常配合CSS计算器属性使用。要创建计数器，需使用counter-reset属性，比如在body元素中设置counter-reset:paracount;
				这样就定义了一个名为paracount的计数器，其值为1。如需指定初始值则可以使用counter-reset:paracount
				10;如果要一次多声明几个计数器，可以这样：counter-reset:paracount 10
				othercounter;也可以象前面一样带上初始值。计数器初始化后就能作为content属性的值来跟:before和:after一起使用来指定样式了。比如::before{ content:
				counter(paracount)".
				";，这条语句的效果是将当前计算器呈现在所匹配的元素之前，后面还要加一个句点和空格。counter-increment属性用来设置计数器的增量，它的值为计数器名称，比如：counter-counter:paracount
				2;。默认增量为1，可在后面添加增量大小。
			</li>
		</ul>
		<p>学好选择器是高效使用CSS的关键。</p>
	</article>
	<article>
		<h1>第18章 使用CSS选择器（第II部分）</h1>

		<p>伪类为基于某些共同特征选择元素提供了方便。结构性伪类有一个冒号前缀比如:empty，可单独使用，也可与其它选择器组合使用。比如:p:empty。下面是常用的结构性伪类选择器：</p>
		<ul>
			<li>:root 匹配文档中的根元素，即html元素。</li>
			<li>子元素选择器，共有四种
				<ul>
					<li>:first-child
						选择元素的第一个子元素。如是不与其它选择器配合，则表示任意元素的第一个子元素，下同。因此，继续前面的示例，可以用p>span:first-child来表示p元素的第一个span直接子元素。
					</li>
					<li>:last-child 选择元素的最后一个子元素</li>
					<li>:only-child 选择元素的唯一子元素，如果元素有多个子元素（包括直接或间接子元素）则不会被选择。</li>
					<li>:only-of-type
						选择元素指定类型的唯一子元素，即有两个相同子元素排在一起时无法匹配。比如，定义p:only-of-type，将匹配在一个父元素下只有一个p元素的情形，对于父元素下有一个以上p元素则不匹配。与其他选择器结合使用可以缩小匹配范围。
					</li>
				</ul>
			</li>
		</ul>
		<p>:nth-child 与子元素选择器类似，但它可以指定一个索引以匹配特定位置的元素。有以下四种方式：</p>
		<ul>
			<li>:nth-child(n) 选择父元素的第n个子元素</li>
			<li>:nth-last-child(n) 选择父元素的倒数第n个子元素</li>
			<li>:nth-of-type(n) 选择父元素定义类型的第n个子元素（参考上面的only-of-type的说明，这样翻译不好理解）</li>
			<li>:nth-last-of-type(n) 选择父元素定义类型的倒数第n个子元素</li>
		</ul>
		<p>
			UI伪类选择器可以根据元素的状态匹配元素。有些元素有启用或禁用状态，这时可以用:enabled和:disabled选择器来修饰。使用:checked可以选中由checked属性或用户勾选的单选按钮或复选框。:default选择器从一组类似的元素中选择默认元素，比如，提交按钮总是表单的默认按钮，那么它就对此进行渲染，它常与outline属性一块使用。:valid和:invalid分别匹配符合和不符合他们输入验证要求的input元素。对于限定范围的元素，比如range和number，:in-range选择器匹配位于指定范围内的input元素，:out-of-range选择器匹配位于指定范围之外的元素。:required匹配具有required属性的input元素，:optional选择器匹配没有required属性的input元素。</p>

		<p>
			动态伪类选择器是可以根据条件的改变匹配元素，是相对固定状态来说的。:link伪类匹配超链接，:visited选择器匹配已访问过的超链接。:hover选择器匹配用户鼠标悬停其上的元任意元素，它会匹配多个嵌套元素。:active匹配当前被用户激活的元素，一般指鼠标按下或触摸屏上手指按压时。:focus选择器匹配当前获得焦点的元素，这个比较有用，可以突出现示得到焦点的input元素。</p>

		<p>:not否定选择器，可以对任意选择取反，比如:not([href *= "press"])，这个匹配子元素没有包含apress字符串的href属性的所有元素。</p>

		<p>:empty 匹配没有定义任何子元素的元素，这个选择器不好演示，因为它匹配的元素没有公司行何内容。</p>

		<p>:lang 匹配基于lang属性值的元素。比如，:lang(en)。</p>

		<p>:target匹配基于id属性导航（用#号加id属性值导航到元素）值的元素。在通过网页URL#id值来访问页面时，拥有id值的元素就会用这个样式来渲染。<a
				href="./cssexapmle.html#mytarget">点击此处查看示例</a></p>
	</article>
	<article>
		<h1>第19章 使用边框和背景</h1>

		<p>简单的边框有三个关键属性：border-width（用来设置边框宽度），border-style（用来设置边框类型），border-color（边框颜色）。</p>

		<p>border-width的值可以使用CSS常规单位，也可以使用边框绘制区夫荣妻贵的百分数，以及thin/medium(默认值）/thick中的一个。</p>

		<p>border-style默认值为none即无边框，可选值用以下几个:<span style="border-style: dashed">dashed 破折线式边框</span> <span
				style="border-style:dotted;">dotted 圆点线式边框</span> <span style="border-style: double">double 双线式</span>
			<span style="border-style: groove; border-color:gray;">groove 槽线式</span> <span
					style="border-style: inset; border-color: gray;">inset 内嵌效果</span> <span
					style="border-style: outset; border-color:gray;">outset 外凸效果</span> <span
					style="border-style: ridge; border-color: gray;">ridge 脊线边框</span> <span
					style="border-style: solid;">solid 实线边框</span></p>

		<p>对于有立体效果的groove/inset/outset/ridge样式，需要border-color属性，如果使用默认值，将失去效果，上边的演示值为gray。</p>

		<p>
			如果需要单独定义一条边的属性，可分别在中间加入表示边框位置的top/right/bottom/left，比如border-bottom-style，border-left-color。如果不用一条边一条边定义的话，也可以使用border属性将所有的三个属性全部写入。比如：border:solid
			medium black。</p>

		<p>
			可以使用边框的radius特性创建圆角边框，可用值有五个，即分别定义四个角的border-top-left-radius/border-top-right-radius/border-bottom-left-radius/border-bottom-right-radius，以及一次设置四个解的border-radius，使用一对或四对长度值或百分数值，由/字符分割。</p>

		<p style="border: solid blue 1px; border-radius: 8px / 8px;">
			指定两个半径值即可定义一个圆角，第一个值为水平曲线半径，第二个值为垂直曲线半径，比如这个段落。如果只提供一个值，那么表示水平半径和垂直半径相同，比如：border-top-left-radius:
			5px;。也可以border-radius一次为四个角指定一个值或在一个值里面写上四个解的不同值（要注意，这里垂直和水平半径需要用/分开）。比如下面这样：</p>
		<pre>
			#first
			{
				border-radius: 20px / 15px; 	这里定义的是四个角，每个角的水平半径为20px，垂直半径为15px
			}
			#second
			{
				border-radius: 50% 20px 25% 5em / 25% 15px 40px 55%;	这里分别定义四个角，/左边的四个值为四个水平半径，右边四个值为垂直半径
			}
		</pre>
		<p>如果圆角遮挡了文字，而添加padding属性增大内容与边框间距来解决。</p>

		<p>可以使用图像创建真正自定义的边框（这个太神了），问题是这个需要使用浏览器厂商的前缀（因为IE不支持，那就不用IE好了，不用加前缀。）可用的属性列表如下：</p>
		<ul>
			<li>border-image-source 设置图像来源，其值为none或url(图像URL）</li>
			<li>border-image-slice 设置分分图像的偏移，1~4个长度值或百分数，受图像高度的影响</li>
			<li>border-image-width 设置图像边框的宽度 auto或1~4个长度值或者百分数</li>
			<li>border-image-outset 指定图像边框向外扩展的部分，1~4个长度值或者百分数</li>
			<li>border-image-repeat 设置图像填弃边框区域的模式，stretch（拉伸）/repeat/round（平铺）中的一个或两个值</li>
			<li>border-image 在一个属性中定义上面的所有属性，而且，前面的四个属性当前没有浏览器支持。</li>
		</ul>
		<p>将图像用作边框的关键是切分图像，指定图像边框向内偏移的值，浏览器会使用这些值来将图像切分成9块。如下图：</p>
		<img src="images/border_image_describe.bmp" alt="CSS切分背景图像示意图"/>

		<p>
			要切分图像需要提供四个边框在四个方向上向内偏移的值，可用长度值或相对图像尺寸的百分数，可以提供四个数也可以提供两个数（分别表示水平和垂直），还可以用一个数。切后后生成8个切分图，1，3，6，8用来绘制4个解，2，4，5，7用来绘制四条边。注意，切分值和宽度值之间用/分隔，比如：-moz-border-image:
			url(images/border_image_describe.png) 30 /50 px，这个表示用30像素来切，然后，每个边框宽图都是50像素。</p>

		<p>直到现在， border-image也没有得到很好的和统一的支持，先知道怎么用，放放再说。</p>

		<p>
			盒模型的另一个可见区域是元素的内容。元素内容可应用背景样式属性，包括background-color/background-image/background-repeat/background-size（设置背景图像尺寸，除了使用长度值还可以是百分数及预定义的值：contain等比例缩放，使其宽高中的较大者与容器宽或高重合，确保图像始终包含在容器内/cover等比例缩放使图像至少覆盖容器/auto默认值，以本身尺寸显示）/background-position（背景图像位置，以左上顶点的坐标值定义，还可使用top/bottom/left/right/center等预定义值）/background-attachment（是否随页面滚动，fixed（固定在视窗上，不随内容一起动）/local(与内容一起滚动）/scroll(固定在元素上，不随内容一起动）/background-clip（裁剪方式，确定背景的绘制区域，可用以下三个值：border-box
			在边框盒子内部绘制背景颜色和图像/padding-box在内边距盒子内部绘制/content-box在内容盒子内部绘制）/background-origin（绘制背景图的起始位置，它可用的值与前面的background-clip一样）以及简写形式background。</p>

		<p>CSS3使用box-shadow为元素的盒子添加了阴影效果，它的值组成如下（注意顺序，也可以在一个语句中为一个元素定义多个阴影，用逗号分开即可）：box-shadow:hoffset voffset blur
			spread color inset</p>
		<ul>
			<li>hoffset 水平偏移量，一个长度值，正数代表阴影向右偏移，负数向左</li>
			<li>voffset 垂直偏移量，一个长度值，正数代表阴影位于盒子下方，负数代表上方</li>
			<li>blur (可选）指定模糊值，一个长度值，值越大边界越模糊，默认为0，边界清晰</li>
			<li>spread （可选）指定阴影的延伸半径，一个长度值，正值代表阴影向盒各个方向延伸扩大，负值代表阴影延相反方向缩小</li>
			<li>color 设置阴影的颜色</li>
			<li>inset （可选）将外部阴影设置为内部阴影（内嵌到盒子中）</li>
		</ul>
		<p>示例：box-shadow:5px 4px 10px 2px gray, 4px 4px 6px gray inset;这行代码定义了两个阴影，后面是一个内部阴影</p>

		<p>轮廓不属于页面，因此，应用轮廓不会影响布局，它只用于引起用户对某个元素的注意，比如必须按压的按钮或数据输入中的错误。它的可用属性如下：</p>
		<ul>
			<li>outline-color 设置外围轮廓的颜色</li>
			<li>outline-offset 设置轮郭距离元素边框的偏移量</li>
			<li>outline-style 设置轮廓样式，可选值与border-style一样</li>
			<li>outline-width 宽度</li>
			<li>outline 在一条语句中定义上面所有的属性</li>
		</ul>
	</article>
	<article>
		<h1>第20章 使用盒模型</h1>

		<p>
			CSS可将元素解析为一个个盒子，用于页面的布局。内边框padding会在元素内容和边框之间添加空白，使用内边距可避免圆角边框覆盖内容。外边距是元素边框和页面上围绕在它周围的所有东西（包括父元素和其他元素）之间的空白区域。注意，外边距只应用于块元素，如果元素默认的display属性为inline（即行内元素）需要将其设置为block才能使margin属性生效。</p>

		<p>
			控制元素的尺寸，除width和height外还有min-width及min-height和max-width和max-height，使用这四个属性尤其是min属性可以防止浏览器变小时影响布局，还可以使用box-sizing属性定义尺雨调整应用到盒子的哪一部分（content-box/padding-box/border-box/margin-box)。</p>

		<p>如果内容溢出盒子时，可设置overflow-x和overflow-y(或者使用它们的简写属性overflow）来定义溢出方式处理。可用值如下：</p>
		<ul>
			<li>auto 浏览器自行处理溢出内容。设置该值后无论是否溢出都有滚动条</li>
			<li>hidden 多余部分直接剪掉</li>
			<li>no-content 直接全部移除</li>
			<li>no-display 隐藏全部内容，这一条和上一条主流浏览器都不支持，幸好不支持</li>
			<li>scroll 显示滚动条</li>
			<li>visible 默认值，不管是否溢出都显示元素内容</li>
		</ul>
		<p>visibility属性用于控制元素的可见性，有三个值可用：collapse 元素不可见且在布局中不占据空间（只支持表相关的元素，某些浏览器不支持，只Firefox支持）；hidden
			元素不可见，但在页面布局中占据空间；visible 默认值，元素可见。</p>

		<p>display属性用于改变元素的盒类型。display可用值如下：</p>
		<ul>
			<li>block 定义为块级元素</li>
			<li>inline 定义为行内元素</li>
			<li>inline-block 整体上作为行内元素显示，即在垂直方向上该元素和周围内容一样，但行内可用块元素的width/height/margin等块元素属性</li>
			<li>run-in 这种类型的最后效果取觉于周围元素，分为三种情况
				<ul>
					<li>如果插入元素包含一个display属性为block的元么，那么此元素即为块级元素</li>
					<li>如果插入元素的相邻兄弟元素是块级元素，那么插入元素就是兄弟元素中的第一个行内元素</li>
					<li>其他情况均作为块级元素对待</li>
				</ul>
			</li>
			<li>none 不显示</li>
		</ul>
		<p>float 创建浮动盒。浮动盒会将元素的左边界或右边界移动到包含块或别一个浮动盒的边界。它有三个可用值：</p>
		<ul>
			<li>left 移动元素，使其左边界挨着包含块的左边界，或另一个浮动元素的右边界</li>
			<li>right 移动元素，使其右边界挨着包含块的右边界，或另一个浮动元素的左边界</li>
			<li>none 默认值，元素位置固定</li>
		</ul>
		<p>如果设置了多个浮动元素，它们会一个挨着一个地堆叠在一起，使用clear属性可以指定浮动元素的一个边界或两个边界示能挨着另一个浮动元素。它有四个值可用：</p>
		<ul>
			<li>left 元素的左边界不能挨着另一个浮动元素，清空左边</li>
			<li>right 清空右边，元素的右边界不能挨着另一个浮动元素</li>
			<li>both 清空两边，元素的左右边界都不能挨着其它浮动元素</li>
			<li>none 元素的左右边界都挨着浮动元素</li>
		</ul>
	</article>
	<article>
		<h1>第21章 创建布局</h1>

		<p>CSS3布局模型有两个但还有待成熟，还没没有浏览器支持。要创建复杂的页面布局可使用<a href="http://www.blueprintcss.org">Blueprint</a>框架。</p>

		<p>控制内容最简单的方式就是通过定位，实现浏览器精确布局元素。</p>

		<p>position属性设置了元素的定位方法，可用以下四个值实现不同定位：</p>
		<ul>
			<li>static 默认值，普通布局，没有定位，元素出现在正常的流中（忽略 top, bottom, left, right 或者 z-index 声明）。</li>
			<li>relative 相对布局，元素位置相对于以static确定的定位</li>
			<li>absolute 绝对定位，元素相对于position值不为static的第一位祖先元素定位</li>
			<li>fixed 元素相对于浏览器窗口来定位，元素位置依据浏览器边界确定，不随内容滚动<</li>
		</ul>
		<p><a href="position.html">点击此处查看示例。</a></p>

		<p>z-index 设置元素的相对层叠顺序，可以是复数，值越小，位置越靠下。</p>

		<p>可使用columns创建多列布局，像报纸那样。Internet Explorer 10 和 Opera 支持多列属性。Firefox 需要前缀 -moz-。Chrome 和 Safari 需要前缀
			-webkit-。column-rule-width设置列间隔的宽度，column-rule-style设置列之间间隔的样式规则与border-style属性值相同，column-rule-color设置列间隔的颜色，注意，如果不设置column-rule-style属性，则颜色也无从显示。column-rule以上三个属性的简写。column-gap指定列之间的距离。column-fill指定内容在列与列之间的分布方式，它有两个值可用：balance-不同列之间的长度差异尽可能小；auto-按照顺序填充列。column-span指定元素横向能跨多少列，有两个值可用none/all,column-width指定列宽，columns是column-span和column-width的简写形式。<a
					href="http://www.w3school.com.cn/tiy/t.asp?f=css3_column-count">可在些演示一下</a></p>

		<p>
			弹性布局也称为伸缩布局，在CSS3中得到了增强，为display属性添加了一个新值box，并定义了其它几个属性。使用弹性布局可以创建对浏览器窗口调整响应良好的流动界面，这是通过在包含元素之间分配容器块中未使用的空间来实现的。这个是CSS3的得新新特性，但未未得到全面支持，需要加入浏览器前缀，比如：-moz-box-flex。box-flex属性会告诉浏览器大小变化时，元素的尺寸是弹性的。示代代码说明：</p>
		<pre>
			首先定义外围的盒子元素
			#container
			{
				display: -webkit-box;
			}

			然后定义合子内部需要伸缩布局的元素
			#first
			{
				-webkit-box-fles:3;	//这个值设置为3的意思是浏览器为其分配的多余空间是id为second的元素的3倍
			}
			#secont
			{
				-webkit-box-flex:1;
			}
		</pre>
		<p>处理垂直空间，使用box-align属性，它可用的值有四个：</p>
		<ul>
			<li>start 元素沿容器顶边放置，任何空空间都在其下方显示</li>
			<li>end 元素沿容器的底边放置，任何空空间都在其上方显示，这个可用于手机上底部菜单的设计，不需要计算屏高了</li>
			<li>center 多余空间被分为两部分，分别显示在元素的上方和下方</li>
			<li>strech 调整元素高度，以填充可用空间</li>
		</ul>
		<p>box-pack定义了当所有可伸缩元素都达到最大尺寸的情况下，多余空间仍未分配完毕时应该如何处理。它也有四个值可用：</p>
		<ul>
			<li>start 元素从左边界开始放置，任何未分配的空间都显示到最后一个元素的右边</li>
			<li>end 元素从右边界开始放置，任何未分配的空间都显示到第一个元素的左边</li>
			<li>center 多余空间平无措分配到第一个元素的左边和最后一个元素的右边</li>
			<li>justify 多余空间均匀分配到各个元素之间</li>
		</ul>
		<p>书上的介绍已经陈旧，<a href="http://www.w3.org/html/ig/zh/wiki/Css3-flexbox/zh-hans#.E6.A6.82.E8.BF.B0">新的标准参考此处</a>
		</p>

		<p>
			创建表格布局：表格元素曾用于网页布局，后来CSS一直致力于替代表格，现在CSS支持table属性布局了。要使用表格布局需要先设置元素的display属性为table，将此元素作为表格。与table元素相应的table属性如下：</p>
		<ul>
			<li>table 类似table元素</li>
			<li>inline-table 类似table元素，但它用来创建一个行内元素（在行内插入表格，当然行高要足够。</li>
			<li>table-caption 类似caption元素</li>
			<li>table-column 类似col元素</li>
			<li>table-column-group 类似colgroup元素</li>
			<li>table-header-group 类似thead元素</li>
			<li>table-row-group 类似tbody元素</li>
			<li>table-footer-group 类似tfoot元素</li>
			<li>table-row 类似tr元素</li>
			<li>table-cell 类似td元素</li>
		</ul>
		<p>在应用方面，需要将表格属性分配给相应元素的display属性，<a href="csstable.html">示例</a>
			比如：table，table-row分配为div这样的块级元素(table如果是页面唯一元素，可用id定义），而table-cell则分配给比div范围小一点的p元素（如果不是唯一元素，使用class属性）。</p>
	</article>
	<article>
		<h1>第22章 设置文本样式</h1>

		<p>
			基本文本样式：对齐文本text-align有六个值可用：left/right/center/start/end（这是针对于本地语言使用的边界，比如在处理从右到左的语言时它就要强于left/right的定义）/justify(这个值配梧text-justify一起使用，指定文本添加空白的方式。text-justify可用的值如下：）。</p>
		<ul>
			<li>auto 由浏览器选择对齐规则</li>
			<li>none 禁用文本对齐</li>
			<li>inter-word 空白分布在单词之间，适用于英语等词间有空的语言</li>
			<li>inter-ideograph 空白分布在单词、表意字之间，且文本两端对齐，适用于汉语、日文和韩文等语言</li>
			<li>inter-cluster 空白分布在单词、字形集的边界，适用于泰文等无词间空格的语言</li>
			<li>distribute 空白分布在单词、字形集的边界，但连续文本或草体除外</li>
			<li>kashida 通过拉长选定字符调整对齐方式（仅适用于草体）</li>
		</ul>
		<p>
			可以设置样式的whitespace属性来定能浏览器对空白的处理方式。它可用五个值：normal（默认值，空白符被压缩，文本行自动换行）/nowrap（空白符被压缩，文本不换行）/pre（空白符被保留，这与pre元素效果是一样的）/pre-line（空白符被压缩，文本只在一排行满或遇到换行符时换行）/pre-wrap（空白符被保留，文本会在一行排满或遇到换行符时换行）</p>

		<p>定义文本方向使用direction属性，它有两个值ltr和rtl，但是此属性已经从CSS的最新草案移除，也有恢复的可能。</p>

		<p>指定单词（word-spacing)、字母(letter-spacing)以及行间距(line-height 设置行高)。</p>

		<p style="text-indent: 2em">首行缩进，使用text-indent属性，它的值可用长度值或百分比。这一段的首行缩进两个字符只需定义text-indent:2em;</p>

		<p>装饰文本用text-decoration属性，它可用的值如下：none（无装饰，默认值）/<span
				style="text-decoration: underline">underline（下划线）</span>/<span style="text-decoration: overline">overline（上划线）</span>/<span
				style="text-decoration:line-through">line-through（删除线）</span>。 </p>

		<p>转换大小写使用text-transform属性，可用值如下：none/<span style="text-transform: capitalize">capitalize 首字母大写</span>/uppercase/lowercase。
		</p>

		<p style="text-shadow:2px 2px lightgrey">
			创建文本阴影使用text-shadow属性，可用属性值如下：h-shadow（阴影水平偏移量）/v-shadow（阴影垂直偏移）/blue（定义阴影的模糊值）/color（定义阴影颜色）</p>

		<p>定义字体，font-family 设置显示的字体，多种希望使用的字体按优先顺序排列。font-size 字体大小 font-style 字体样式 font-variant 是否以小型大写字母显示 font-weight
			粗细 font 简写形式。</p>

		<p>@font-face定义web字体，使用web字体可以直接下载web字体并使用在自己的页面上，不需要用户做什么。这个非常有用！格式如下：</p>
		<pre>
			@font-face
			{
				font-family: 'MyFont';
				font-style: normal;
				src: url('http://^^^^^/MyFont.woff');
			}
		</pre>
		<p>注意，这里使用的字体格式是woff格式，Web字体有多种格式，woff格式得到了最为广泛的应用。</p>
	</article>
	<article>
		<h1>第23章 过渡、动画和变换</h1>

		<p>这些效果支持不是很全面，需要加入厂商前缀。不要用在不属于任务核心的元素上，尽量不滥用。</p>

		<p>过渡效果一般是由浏览器直接改变元素的CSS属性实现的，比如，使用:hover选择器， 在鼠标悬停在元素上之时改变元素的样式。<a href="transition.html">查看示例</a></p>

		<p>过渡特性可以控制应用新属性值的速度，这些特性已得到浏览器的支持，可以不用加厂商前缀了。可以逐渐改变元素外观。可用的属性有以下几个（时间都是以ms为单位）：</p>
		<img style="float: right" src="images/transition_timing_function.jpg">
		<ul>
			<li>transition-delay 指定过渡开始的延迟时间，在触发的动作发生生，不马上发生过渡，而是延迟一会再</li>
			<li>transition-duration 指定过渡的持续时间</li>
			<li>transition-property 指定应用过度的属性，比如background-color,color,padding等发生变化的属性名称，多个属性用逗号分开</li>
			<li>transition-timing-function
				指定过渡期间中间值的方式，使用过渡时，浏览器会为每个属性计算初始值和最终值之间的中间值，表示为四个点控制的三次贝塞尔曲线，有五种预设曲线可选：ease（默认值）/linear/ease-in/ease-out/ease-in-out。五种值的变化趋势如右图。linear是变化最为浏畅的一个
			</li>
			<li>transition 在一条声明中指定所有过渡细节的简写</li>
		</ul>
		<p>CSS动画本质上增强的过渡。在过渡的过程中有了更多的选择控制和灵活性。可用的动画属性如下：</p>
		<ul>
			<li>animation-delay 设置动画开始前的延迟</li>
			<li>animation-direction
				设置动画循环播放的时候是否反向播放，有两个可用值normail（默认值，正序），alternate动画先向前播放，然后反向播放，相当于animation-iteration-count的值为2
			</li>
			<li>animation-duration 设置动画播放的持续时间，单位为ms的数值</li>
			<li>animation-iteration-count 设置动画的播放次数，infinite无限播放或定义次数数值</li>
			<li>animation-name 指定动画名称 保存关键帧的定义段，注意，因为当前只webkit系的浏览器支持，所以应当在定义段中加-webkit-前缀，而此处名称不需任何前缀</li>
			<li>animation-play-state 允许动画暂停和重新播放，两个可选值running/paused，在应用中需要使用JavaScript来改变这个属性值来实现</li>
			<li>animation-timing-function 定义如何计算中间动画值，参考前面的动画曲线取值，</li>
			<li>animation 简写</li>
		</ul>
		<p>动画是由两部分定义的，上面的列表定义了动画的属性，第二部分需要用@key-frames定义动画内容。动画的支持还不稳定，而且只webkit系的浏览器支持。<a href="animation.html">示例</a>
		</p>

		<p>当前仅webkit系的浏览顺支持动画属性，因此，要插入-webkit-前缀。关键帧的表示方法，如下：@key-frame定义的关键属性分几个部分，如下：</p>
		<ol>
			<li>设置初始状态，用from子句，动画的初始值来字元素自身，但可以使用from子句指定另一组初始值</li>
			<li>指定中间关键帧，通过百分数子句实现，中间帧的作用有二：一是定义新的变化速率；一是定义属性值以创建更复杂的动画，这样就可以更改变化曲线，在直线变化的中间插入其它变化</li>
		</ol>
		<p>当然，也可以在初始布局中应用动画，不一定非在动作中激活。只需要在元素的属性中定义动画就可以了，
			比如，直接在#banana中定义，这样会在页面加载时自动使用动画。一组关键帧可用于多个动画。比如下面的GrowShrink，可被多个动画定义调用。同一个元素也可用多个关键帧组，只需用逗号将名称分开即可。</p>
		<pre>
			#banana:hover, #apple /* 多个元素可以定义相同的动画 */
			{
				/* 此处定义当id为banana的元素在鼠标移上之后的动画播放要素 */
				-webkit-animation-delay: 100ms;	/* 定义动画开始时间，在得到鼠标指针后100ms */
				-webkit-animation-duration: 500ms; /* 这是动画单次时长 */
				-webkit-animation-iteration-count: infinite; /* 这是循环次数，定义为无限，或指定数字 */
				-webkit-animation-timing-function: linear; /* 这是变化方式，一般就用linear直线变化，其它变化不是很明显 */
				-webkit-animation-name: 'GrowShrink','ColorSwap';	/* 这是定义动画段名称，用它来定义关键帧，后面的ColorSwap是另一个关键帧，这里只是为了说明一个元素可应用多个关键帧组 */
			}
			@-webkit-keyframe GrowShrink /* 这里的名称与-webkit-animation-name指定的相同，这一段定义动画的内容，关键帧-动画的节点帧，从一个关键帧到另一个关键帧之前的变化由计算生成 */
			{
				from
				{
					//此处定义初始关键帧
				}
				25%
				{
					//此处定义中间关键帧
				}
				50%
				{
					//此处定义中间关键帧
				}
				...
				to
				{
					//这一节定义最终关键帧
					//这是动画结束后的样子
				}
		</pre>
		<p>CSS3实现了元素的线性变换，可以旋转、缩放、倾斜和平移元素。transform属性为元素应用变换，它的可用值是一组预定函数，如下：</p>
		<ul>
			<li>translate(长度值或百分数值） 在水平translateX()、垂直translateY()方向或两个(translate())方向上平移元素。</li>
			<li>scale(数值) 在水平方向sclaeX()、垂直方向scaleY()或者两个方向scale()上缩放元素</li>
			<li>rotate(角度） 旋转元素，角度值的表示方式为数字后面跟deg，比如:-45deg表示逆时针旋转45度，正数则顺时间旋转</li>
			<li>skew(角度) 在水平方向skewX()、垂直方向skew(Y)或者两个方向skew()上使元素倾斜一定角度</li>
			<li>matrix(4~6个数值，逗号隔开) 指定自定义变换，大多数浏览器不支持z轴缩放，因此最后两个数字可以省略（有些情况必须省略）</li>
		</ul>
		<p>默认使用元素的中心作为变幻起点，可是可以用transform-origin来选择：</p>
		<ul>
			<li>% 指定元素x轴或y轴的起点</li>
			<li>长度值 指定距离</li>
			<li>left/center/right 指定x轴上的位置</li>
			<li>top/center/bottom 指定y轴上的位置</li>
		</ul>
		<p>当然，变幻也可作为动画处理，只需要定义关键帧就可以了。但是当前变幻支持的非常少，只IE11实现了。因此，暂时放弃这种应用。</p>
	</article>
	<article>
		<h1>第24章 其他CSS属性和特性</h1>

		<p>
			color属性一般用来设置前景色，通常就是文本的颜色。使用rgba(255,255,255,0.7)这样的函数设置元素颜色，最后一位小于1表示可以让它透明。可果只要前景透明的话，也可以使用opacity属性，它的值定义为小于1的小数就表示透明度。</p>

		<p>表示样式相关的几个属性：border-collapse
			设置相邻单元素的处理样式有两个值collapse(不要为相邻的两个元素绘制两个边框）/separate（默认值，为所有单元格绘制边框）。如果使用了separate属性，可以定义border-spacing属性来设置单元格的间距。empty-cells
			属性定义了空单元格的处理方式，有两个值hide（默认值，作为空白区域，什么也不显示）/show（显示为空的单元格）。caption-side属性来定义表格子元素caption的显示位置（默认为表格顶部），它有两个值top（默认）/bottom。浏览器显示表格采用的方法是由table-layout决定的，默认值为auto，即由浏览器根据每列中最宽的单元格胡定，使用另一个值fixed也可以禁用自动布局，这样就将只按定义的列宽来显示，如果不定义列宽的话，所有列宽将平均分配。</p>

		<p>列表样式相关的几个属性：list-style-type 指定列表中使用的标记的类型（标记类型见下面）。list-style-image
			指定图像作为列表标记，它的值为图像URL，比如:ul{list-style-image: url("banana.png");}。list-style-position
			指定标记相对于列表项目盒子的位置，有两个值inside(默认值，内部）/outside（外部）。list-style 以上所有的简写。</p>

		<p>list-style-type的部分可用样式值，具体的样式请参照<a href="http://www.23.org/TR/css3-lists">W3C的完整样式列表</a>。</p>
		<ul>
			<li>none 默认值，没有</li>
			<li>box/checkbox/circle/diamond/disc/dash/square 使用指定的形状标记，注意，不是每种浏览器都支持所有形状</li>
			<li>decimal 使用十进制数字作为标记</li>
			<li>binary 使用二进制数字作为标记</li>
			<li>lower-alpha 使用小写字母作为标记</li>
			<li>upper-alpha 使用大写字母作为标记</li>
		</ul>
		<p>
			通过设置元素的cursor属性设置当鼠标滑过元素时的光标样式，可用值如下：auto/crosshair/default/help/move/pointer/progress/text/wait/n-resize/s-resize/e-resize/w-resize/ne-resize/nw-resize/se-resize/sw-resize。</p>
	</article>
</section>
<section class="content">
	<h1>第四部分 使用DOM</h1>

	<p>DOM（Document Object Model，文档对象模型）允许我们使用JavaScript来探查和操作HTML文档里的内容。</p>
	<article>
		<h1>第25章 理解DOM</h1>

		<p>
			DOM是一组代表HTML文档各个元素的对象集合，它文档和JavaScript之间的桥梁。作为显示HTML文档过程的一个步骤，浏览器会解析HTML并创建一个模型，这个模型保存HTML元素之间的层级关系，每个元素都由一个JavaScript对象表示。模型里的每个对象都有若干属性和方法，可用来修改对象的状态并反应到对应的HTML元素上。层级关系示例如下图：</p>
		<img src="images/dom_model.jpg" alt="HTML文档里的元素层级关系示例">

		<p>
			DOM同HTML一样也存在着不一致性，HTML5试图将DOM核心规范化，但并没有解决。应对这种碎片化有两种方式：一是使用某个JavaScript库（比如jQuery），使用库的优点是一致性，但缺点是只能使用库支持的那些功能；二是保守方式，只使用被广泛支持的功能，不过，同样的功能在不同的浏览器实现仍的差异，而且有些功能可能在发展中会变化或被移除。</p>

		<p>接下来是后面几章的简介，DOM对象的属性和方法列表，省略。</p>
	</article>
	<article>
		<h1>第26章 Document对象</h1>

		<p id="apples">
			Document对象是通向DOM功能的入口，它提供当前文档的信息以及一些可供探索、导航、搜索或操作结构与内容的功能。Document对象使用全局变量document来访问。下面的文档地址就是用document.URL来获得的。</p>
		<script>
			document.writeln('<pre>URL: ' + document.URL);
			document.writeln('</pre>');
			apples = document.getElementById("apples");
			apples.style.border = 'medium double black';
		</script>
		<p>
			可以将HTMLElement对象理解为一个接口，提供了基本功能以代表HTML元素，所有对象都可以看作是它的子类或是它的实现。getElementsByTagName()方法返回的结果就是HTMLElement对象所组成的一个集合。</p>

		<p>要在JavaScript中操作一个HTML元素，首先要用元素来初始化一个对象变量，比如：apples = document.getElementById('apples');
			然后就可以通过apples来操作拥有此ID的元素了，也可以使用元素名或class名来获得元素的集合。进一步，使用对象变量可以修改元素的样式，比如本章的第一段就是用下面的样式修改的：apples.style.border
			= "medium double black";，这将为元素生成一个内嵌样式（当然是内嵌，不然会被其它样式覆盖的）。</p>

		<p>使用document对象可获得的文档元数据如下：</p>
		<script>
			document.writeln('<pre>');

			document.writeln('characterSet 返回文档的字符编码（只读）: ' + document.characterSet);
			document.writeln('charset 获取或设置文档的字符编码: ' + document.charset);
			document.writeln('compatMode 获取文档的兼容性模式:' + document.compatMode);
			document.writeln('defaultCharset 获取浏览器使用的默认字符编码:' + document.defaultCharset);
			document.writeln('defaultView 返回当前文档的window对象:' + document.defaultView);
			document.writeln('dir 获取或设置文档的文本方向:' + document.dir);
			document.writeln('domain 获取或设置当前文档的域名:' + document.domain);
			document.writeln('implementation 提供可用DOM功能的信息:' + document.implementation);
			document.writeln('lastModified 返回文档的最后修改时间:' + document.lastModified);
			document.writeln('location 提供当前文档的URL信息:' + document.location);
			document.writeln('readyState 返回当前文档状态（只读）:' + document.readyState);
			document.writeln('referrer 返回链接到当前文档的文档URL（就是对应HTTP标头的值:' + document.referrer);
			document.writeln('title 返回或设置当前文档的标题:' + document.title);
			document.write('</pre>');
		</script>
		<p>document.compatMode如果返回CSS1Compat则表示文档尊循某个有效的HTML规范；返回BackCompat表示文档含有非标准功能，已触发怪异模式。</p>

		<p>document.location属性是一个Location对象，它提供文档地址，也可以导航到其他文档上。Location对象的方法和属性如下：</p>
		<ul>
			<li>protocol 获取或设置文档URL的协议部分，比如http或ftp等</li>
			<li>host 获取或设置文档URL的主机和端口部分</li>
			<li>href 获取或设置当前文档的地址，这个属性和后面的assign()方法以及replace()方法都可用来实现网页跳转</li>
			<li>hostname 获取或设置文档URL的主机名部分</li>
			<li>port 获取或设置文档URL的端口部分</li>
			<li>pathname 获取或设置文档URL的路径部分</li>
			<li>search
				获取或设置文档URL的查询（问号串，参数表）部分，比如，对于http://.../ex.html?query=apples&another=oranges，它返回：?query=apples&another=oranges
			</li>
			<li>hash
				获取或设置文档URL的锚（#开头的链接）部分，比如，对于http://.../ex.html#apples它返回：#apples，也可以修改它的值，指文档跳到用它的值指定的id上，比如：document.location.hash="apples"。
			</li>
			<li>assign(URL) 导航到指定URL上</li>
			<li>replace(URL) 清除当前文档并导航到URL所指定的那个文档，这样用户就不能使用后退按钮返回当前文档了</li>
			<li>reload() 重新载入当前文档</li>
			<li>resolveURL(URL) 将指定的URL解析成绝对URL</li>
		</ul>
		<p>
			document.cookie属性用来读取或设置文档所关联的cookie。cookie的形式是name=value的名称对，如果存在多个cookie，那么document.cookie属性会将它们作为结果一起返回，中间以分号隔开。创建cookie时，只需指派一个新的名称/值对，如果这个名称已经存在，那么，就会用值的部分去更新已存在的值。可以添加到cookie中的额外字段，path=path
			设置cookie关联的路径，如果没有指定则默认使用当前文档的路径；domain=domain 设置cookie关联的域名，如果没有则用当前文档的；max-age=时长
			设置cookie的有效期，单位是秒；expires=日期 设置cookie的有效期，值为GMT格式的日期；secure 只有在安全（HTTPS）连接时才会发送cookie。</p>

		<p>
			使用document.readState可以查看浏览器加载和处理HTML到了哪个阶段，document.readystatechange事件则在readyState发生变化的时候触发，两者结合使用时很有效。前者可返回三个不同的值，表示不同状态：</p>
		<ul>
			<li>loading 正在加载和处理此文档</li>
			<li>interactive 文档已被解析，但浏览器还在加载其他资源</li>
			<li>complete 文档已被解析，所有资源加载完毕</li>
		</ul>
		<p>
			document.implementation属性提供浏览器对DOM功能的实现信息。它返回一个DOMImplementation对象，用此对象的hasFeature方法可以判断哪些DOM功能已实现。但是浏览器并不总能正确报告它们实现的功能，因此这个不是很实用。</p>

		<p>document对象提供了一组属性，可返回代表文档中特定元素或元素类型的对象，如下：</p>
		<ul>
			<li>activeElement 返回一个代表当前带有键盘焦点元素的对象</li>
			<li>body 返回一个代表body元素的对象</li>
			<li>Embeds/plugins 以回所有代表embed元素的对象</li>
			<li>forms 返回所有代表form元素的对象</li>
			<li>head 返回一个代表head元素的对象</li>
			<li>images 返回所有代表img元素的对象</li>
			<li>links 返回所有代表文档里具备href属性的a和area元素的对象</li>
			<li>scripts 返回所有代表script元素的对象</li>
		</ul>
		<p>访问这类集合对象有两种方式，一种是将之当作数组用遍历的方式访问；一种是用nameItem方法，它返回集合里带有指定id或name属性值的元素。比如;var srcValue =
			elements.namedItem('apple').src;</p>

		<p>document对象定义了许多搜索元素的方法：getElementById()/getElementByClassName()/getElementByName()/getElementByTagName()
			返回指定类型的元素/querySelector() 返回匹配指定选择器的第一个元素/querySelectorAll()
			返回匹配指定CSS选择器的所有元素，可以同时查找多个选择器，只需用逗号分开即可。<strong>这些方法中除了getElementById()方法之外，其余的方法都可以被元素使用。</strong>。比如:document.getElementById('tblock').getElementByTagName('span');。这种方式称为链式搜索，第二次搜索是基于第一次搜索结果的元素以内的，即搜索第一次搜索结果的子元素。
		</p>

		<p>在DOM树里导航（这个就是以前看DOM没看明白的地方，原来导航是要用JavaScript的，只讲特征没有代码算个屁啊！）：</p>
		<ul>
			<li>childNodes 返回子元素组</li>
			<li>firstChild 返回第一个子元素</li>
			<li>hasChildNodes() 如果当前元素有子元素就返回true</li>
			<li>lastChild 返回最后一个子元素</li>
			<li>nextSibling 返回定义在当前元素之后的兄弟元素</li>
			<li>parentNode 返回父元素</li>
			<li>previousSibling 返回定义在当前元素之前的兄弟元素</li>
		</ul>
		<p><a href="dom.html">这是一个关于导航的示例</a>。 </p>
	</article>
	<article>
		<h1>第27章 使用Window对象</h1>

		<p>有两种方式获得window对象，正规的HTML5方式是在Document对象上使用defaultView属性，另一种则是直接使用所有浏览器都支持的全局变量window。Window对象的属性和方法如下：</p>
		<ul>
			<li>innerHeight/innerWidth 获取窗口内容区域的高度/宽度</li>
			<li>outerHeight/outerWidth 获取窗口的高度/宽度，包括边框和菜单栏等</li>
			<li>pageXOffset 获取窗口从左上角算起水平滚动过的像素数</li>
			<li>pageYOffset 获取窗口从左上角算起垂直滚动过的像素数</li>
			<li>screen 返回一个描述屏幕的Screen对象</li>
			<li>screenLeft/screenX 获取窗口左边缘到屏幕左边缘的像素数，不是所有浏览器都支持</li>
			<li>screenTop/screenY 获取窗口上边缘到屏幕上边缘的像素数，不是所有浏览器都支持</li>
		</ul>
		<p>Widow对象可以用它们与包含文档的窗口进行交互。但这些方法会让用户失去对浏览器窗口的控制，因此应该谨慎使用。</p>
		<ul>
			<li>blur() 让窗口失去键盘焦点</li>
			<li>close() 关闭窗口</li>
			<li>focus() 让窗口获得键盘焦点</li>
			<li>print() 提示用户打印页面</li>
			<li>scrollBy(x,y) 让文档相对于当前位置进行滚动</li>
			<li>scrollTo(x,y) 滚动到指定的位置</li>
			<li>stop() 停止载入文档</li>
		</ul>
		<p>window对象包含一组与用户交互的方法</p>
		<ul>
			<li>alert(message) 向用户显示一个对话框并等侯其关闭</li>
			<li>confirm(message) 显示一个带有确认和取肖提示的对话框窗口</li>
			<li>prompt(message, val) 显示对话框提示用户输入一个值</li>
			<li>showModalDialog(URL) 弹出一个窗口，显示指定的URL，因为被广告滥用，这个功能可能会被用户屏蔽掉了，如果要提示用户注意可以选用jQuery这样的库</li>
		</ul>
		<p>window对象可通过document/history/location这三个属性来返回当前窗口关联的document对象/提供对浏览器历史的访问/提供当前文档地址的详细信息。</p>

		<p>使用windows.history属性返回一个History对象，这个对象可用的属性和方法如下：</p>
		<ul>
			<li>back() 在浏览历史中后退一步</li>
			<li>forward() 前进一步</li>
			<li>go(index) 转到相对于当前文档的某个浏览历史位置，正值是进，负值是退</li>
			<li>length 返回浏览历史中的项目数量</li>
			<li>pushState(state, title, url) 向浏览器历史添加一个条目，但是有约束条件，URL的服务器名和端口号必须与当前文档的相同</li>
			<li>replaceState(state, title, url) 替换浏览器历史中的当前条目</li>
			<li>state 以对象变量返回浏览器历史中关联当前文档的状态数据</li>
		</ul>
		<p>使用pushState可以在浏览历史中保存复杂状态，它的第一个参数可以是对象，第二个参数则被多数浏览器忽略，第三个参数是URL，如果省略则表示当前文档的URL。<a
				href="pushstate.html">示例在此</a></p>

		<p>
			通常情况下不同来源的脚本是不允许进行通信的，但是window对象为HTML5的新功能跨文档消息传递提供了入口。浏览器通过URL的各个组成部分来判断资源的来源。如果两个脚本的协议、主机名和端口号相同，那么它们就被认为拥有同一来源，即使URL的其他部分不一样也是如此。脚本可以使用document.domain属性改变它们的来源，但只能扩展当前URL的涵盖范围。HTML5通过window里的postMessage(message,
			来源)方法可以给另一个文档发送指定的消息。<a href="postmessage.html">示例页面</a>。 </p>

		<p>Window对象可以设置一次性和循环的计时器，计时方法如下（这个不是很实用）：</p>
		<ul>
			<li>clearInterval(id) 撤销某个时间间隔计时器</li>
			<li>clearTimeout(id) 撤销某个超时计时器</li>
			<li>setInterval(function, time) 创建一个计时器，每个time毫秒调用指定的函数，循环执行</li>
			<li>setTimeout(function, time) 创建一个计时器，等待time毫秒后调用指定的函数，只执行一次</li>
		</ul>
	</article>
	<article>
		<h1>第28章 使用DOM元素</h1>

		<p>元素对象提供了一组属性，这些属性所有HTML元素都可以使用，可用来读取和修改元素的数据，可用的属性如下：</p>
		<ul id="element" dir="rtl" lang="zh">
			<li>checked 获取或设置checked属性是否存在（注：这是布尔属性，因此，存在即为true，下同）</li>
			<li>classList 获取或设置元素所属的类列表，这个列表是一个DOMTokenList对象，它有以下成员可用：
				<ul>
					<li>add(class) 给元素添加指定的类</li>
					<li>contains(class) 如果元素属于指定的类就返回true</li>
					<li>length 返回元素所属类的数量</li>
					<li>remove(class) 从元素上移除指定的类</li>
					<li>toggle(class) 如果类不存在就添加它，如果存在就移除它</li>
				</ul>
			</li>
			<li>className 获取或设置元素所属的类列表，之所以这样叫是因为一个class属性可以有多个用空格分开的类定义，用这个属性可以很方便地在类后面添加新的类，注意前面要加空格</li>
			<li>dir 获取或设置dir属性的值</li>
			<li>disabled 获取或设置disabled属性是否存在</li>
			<li>hidden 获取或设置hidden属性是否存在</li>
			<li>id 获取或设置id属性的值</li>
			<li>lang 获取或设置lang属性的值</li>
			<li>spellcheck 获取或设置spelcheck属性是否存在</li>
			<li>tabIndex 获取或设置tabindex属性的值</li>
			<li>tagName 返回标签名（标识元素类型）</li>
			<li>title 获取或设置title属性的值</li>
		</ul>
		<pre>
		<script>
			var results = document.getElementById('element');

			document.writeln('元素名：' + results.tagName);
			document.writeln('id：' + results.id);
			document.writeln('dir：' + results.dir);
			document.writeln('lang：' + results.lang);
		</script>
		</pre>
		<p>元素对象还支持对单个元素的任意属性进行读取和设置，下面列表中的方法和属性实现了这个功能：</p>
		<ul>
			<li>attributes 返回应用到元素上的属性，它近回的值为Attr对象数组，各个属性同时根据位置和名称进行索引。</li>
			<li>dataset 返回以data-开头的属性，它返回的是字符串数组，也可以通过名称来请求值，比如要获得data-fruit属性的值就可以通过dataset['fruit']来获得。</li>
			<li>getAttribute(name) 返回指定属性的值</li>
			<li>hasAttribute(name) 如果元素带有指定的属性则返回true</li>
			<li>removeAttribute(name) 从元素上移除指定属性</li>
			<li>setAttribute(name, value) 应用一个指定名称和值的属性</li>
		</ul>
		<p>元素的文本内容是由Text对象代表的，它在文档模型里表现为元素的子对象，比如p元素的文本内容就表示的t->text。Text对象支持的成员如下：</p>
		<ul>
			<li>appendData(string) 把指定字符串附加到文本块末尾</li>
			<li>data 获取或设置文本</li>
			<li>deleteData(offset, count) 从文本中移除字符串。第一个数字是偏移量，第二个是要移除的字符数量</li>
			<li>insertData(offset, string) 在指定偏移量处插入指定字符串</li>
			<li>length 返回字符串的数量</li>
			<li>replaceData(offset, count,m string) 用指定字符串替换一段文本</li>
			<li>replaceWholeText(string) 替换全部文本</li>
			<li>splitText(number) 将现有的Text元素在指定偏移量处一分为二</li>
			<li>substingData(offset, count) 返回文本的子串</li>
			<li>wholeText 获取文本</li>
		</ul>
		<p>没有什么方法能定义Text元素，只能先找到它们的父元素对象，然后在子对象中查找。这使得它不太容易使用，不过，如果文档结构合理的话，找到父元素也就行了。操作Text时要注意，空白字符是不会被压缩的。</p>

		<p>你可以添加、移除和复制元素，从而修改文档模型，也就是修改DOM的层级结构，因为连接是实时的，所以对层级结构的改动会立即反映到浏览器中。DOM操纵成员如下：</p>
		<ul id="outers">
			<li>appendChild(HTMLElement） 将指定元素添加为当前元素的子元素</li>
			<li>cloneNode(boolean) 复制一个元素</li>
			<li>compareDocumentPosition(HTMLElement) 判断一个元素的相对位置</li>
			<li>innerHTML 获取或设置元素的内容，它只返回元素所有子元素的HTML</li>
			<li>insertAdjacentHTML(pos, text) 相对于元素插入HTML</li>
			<li>insertBefore(newElement, childElement) 在第二个（子）元素之前插入第一个元素）</li>
			<li>isEqualNode(HTMLElement) 判断指定元素是否与当前元素相同，如果多个元素具有相同的类型，还有相同的属性值，其子元素也相同并且顺序一致，那么他们就是相同的。</li>
			<li>isSameNode(HTMLElement) 判断指定元素是否就是当前元素，通过父元素里的标签类型搜索</li>
			<li>outerHTML 获取或设置某个元素的HTML内容，包括元素本身及其所有子元素内容（这是与innerHTML不同的地方）。用这个来实现元素的替换要比使用对象替换更方便。</li>
			<li>removeChild(HTMLElement) 从当前元素上移指定的子元素</li>
			<li>replaceChild(HTMLElement, HTMLElement) 替换当前元素的某个子元素</li>
		</ul>
		<textarea rows="3" id="resultss"></textarea>
		<button id="inner">Inner HTML</button>
		<button id="outer">Outer HTML</button>
		<script>
			var result = document.getElementById('resultss');
			var row = document.getElementById('outers');
			document.getElementById('inner').onclick = function () {
				result.innerHTML = row.innerHTML;
			}

			document.getElementById('outer').onclick = function () {
				result.innerHTML = row.outerHTML;
			}
		</script>
		<p>创建和删除元素<a href="./appendElement.html">示例页面</a>。 </p>

		<p>如果要插入大段的HTML代码必须使用insertAdjacentHTML，它需要两个参数，第一个参数是下表中的某个值，它表明插入的位置，第二个参数是要插入的代码。</p>
		<ul>
			<li>afterbegin 将代码作为当前元素的第一个子元素插入</li>
			<li>afterend 将代码插入当前元素之后</li>
			<li>beforebegin 将代码插入当前元素之前</li>
			<li>beforeend 将代码作为当前元素的最后一个子元素插入</li>
		</ul>
		<p>比如: target.insertAdjacentHTML('afterbegin', '&lt;td&gt;after begin&lt;/td&gt;');。</p>

		<p>修改模型的另一种重要方式是向由Text对象代表的文本块添加元素，对模型进行操作比较繁琐，<a href="listing-18.html">示例代码</a>。这样可以动态改变元素外观，可能会很有用。</p>
	</article>
	<article>
		<h1>第29章 为DOM元素设置样式</h1>

		<p>可以通过document.styleSheets属性访问文档中可用的CSS样式表，它会返回一组对象（CSSStyleSheet）集合代表与文档关联的各个样式表。CSSStyleSheet对象的成员如下：</p>
		<ul>
			<li>cssRules 返回样式表的规则集合，CSSStyleSheet.cssRules属性会返回一个CSSRuleList对象，</li>
			<li>deleteRuse(pos) 从样式表中移除一条规则</li>
			<li>disabled 获取或设置样式表的标用状态，比如：document.styleSheet[0].disabled =
				!document.styleSheet[0].disabled;这样来切换启用/禁用一个样式表
			</li>
			<li>href 返回样式表的href，只有样式表由外部文件载入时它才会有值</li>
			<li>insertRule(rule, pos) 插入一条新规则到样式表中</li>
			<li>media 返回应用到样式表上的媒介限制集合，可以使用CSSStyleSheet.media属笥来访问这些制制，它会返回一个MediaList对象，MediaList对象的方法和属性如下：
				<ul>
					<li>appendMedium(medium) 添加一个新媒介到列表中</li>
					<li>deleteMedium(medium) 从列表中移除一个媒介</li>
					<li>item(pos) 返回指定索引的媒介</li>
					<li>length 返回媒介的数量，比如：sheets[i].media.length</li>
					<li>mediaText 返回media属性的文本值</li>
				</ul>
			</li>
			<li>ownerNode 返回样式所定义的元素</li>
			a
			<li>title 返回样式表title属性的值</li>
			<li>type 返回type属性的值</li>
		</ul>
		<p>第一步是获得定义在文档中样式表的基本信息，比如：使用var sheets =
			document.styleSheets;来获得样式表集合，然后，通过sheets[i]来指向样式表中的表，然后就可以使用样式表中的属性了，比如：sheets[i].type。</p>

		<p>CSSStyleSheet.cssRules属性会返回一个CSSRuleList对象，用这个对象可以访问样式表里的各种样式，它的对象成员如下：</p>
		<ul>
			<li>item(pos) 近观回指定索引的CSS样式（CSSStyleRule）</li>
			<li>length 近观回样式表里的样式数量</li>
		</ul>
		<p>样式表中的每一种CSS样式都由一个CSSStyleRule对象代表，它的成员如下：</p>
		<ul>
			<li>cssText 获取或设置样式的文本（包括选择器）/li>
			<li>parentStyleSheet 获取此样式所属的样式表 CSSStyleSheet</li>
			<li>selectorText 获取或设置样式的选择器文本，比如可以这样修改一个样式表中样式的名称：document.styleSheets[0].cssRules.item(1).selector =
				'#block2';
			</li>
			<li>style 获取一个代表具体样式属性的对象（CSSStyleDeclaration）</li>
		</ul>
		<p>如果要读取通过元素的style属性设置的样式，则需读取HTMLElement对象里定义的style属性值，它会返回一个CSSStyleDeclaration对象。</p>

		<p>要通过DOM完全控制CSS必须使用CSSStyleDeclaration对象（要引用它的话是通过style属性），下面是它的成员：</p>
		<ul>
			<li>cssText 获取或设置样式的文本</li>
			<li>getPropertyCSSValue(name) 获取指定的属性（CSSPrimitiveValue）</li>
			<li>getPropertyPriority(name) 获取指定属性的优先级</li>
			<li>getPropertyValue(name） 获取字符串形式的指定值</li>
			<li>item(pos) 获取指定位置的项目</li>
			<li>length 获取项目的数量</li>
			<li>parentRule 如果存在样式规则就获取它</li>
			<li>removeProperty(name) 移除指定的属性</li>
			<li>setProperty(name, value, priority) 设置指定属性的值和优先级</li>
			<li>style
				获取或设置指定CSS属性的便捷属性，便捷属性是在DOM中定义的与CSS样式属性相对的名称，可用它们来直接设置CSS样式属性，而不必在CSS样式里进行修改，比如document.styleSheets[0].cssRules.item(1).style.paddingTop
				= '10px';它对应的是样式表中第二个项目的的padding-top属性。也可以用style来返回样式的属性。便捷属性一般的命名规则是去掉连字符，将第一个字母大写。
			</li>
		</ul>
		<p>下面的代码可以枚举未知名称的样式定义：</p>
		<pre>
			var placeholder = document.getElementById('placeholder');	//placeholder是一个空的div元素
			displayStyles();

			function displayStyles(){
				var newElem = document.createElement('table');	//创建一个表格，在表格中显示样式属性
				newElem.setAttribute('border', '1');

				var style = document.styleSheets[0].cssRules[0].style;
				for(var i = 0; i < style.length; i++) {
					addRow(newElem, style[i], style.getPropertyValue(style[i]));
				}

				placeholder.appendChild(newElem);
			}

			function addRow(elem, header, value){
				elem.innerHTML += '&lt;tr&gt;&lt;td&gt;' + header + ':&lt;/td&gt;&lt;td&gt;' + value + '&lt;/td&gt;&lt;/tr&gt;';
			}
		</pre>
		<p>操作CSSStyleDeclaration对象可以使用getPropertyPriority方法来查看!important是否已被应用到某个属性上，如果有指定则会返回important，否则返回空字符串。</p>

		<p>可以使用CSSStyleDeclaration.getPropertyCSSValue方法来获取CSSPrimitiveValue对象，这些对象代表了样式里各个属性所定义的值，对象的成员如下：</p>
		<ul>
			<li>cssText 获得一个用文本表示的值</li>
			<li>getFloatValue(type) 获得一个数值</li>
			<li>getRGBColorValue() 获得一个颜色值</li>
			<li>getStringValue() 获得一个字符串值</li>
			<li>primitiveType 获得值的单位类型，这个属性会告诉你属性的值是用什么单位表达的，比如：CSS_NUMBER/CSS_PERCENTAGE/CSS_PX/CSS_CM等等。</li>
			<li>setFloatValue(type, value) 设置一个数值</li>
			<li>setStringValue(type, value) 设置一个基于字符串的值</li>
		</ul>
		<p>
			浏览器用于显示某个元素的CSS属性值集合被称为计算样式。可通过document.defaultView.GetComputedStyle方法获取包含某一元素计算样式的CSSStyleDeclaration对象。用这个方法获得的对象包含了浏览器用来显示元素的所有属性细节，以及各个属性的值，但是无法通过它来修改样式表。</p>
	</article>
	<article>
		<h1>第30章 使用事件</h1>

		<p>
			事件可用来定义一些JavaScript函数，使它们响应某个元素状态的改变，比如元素获得或失去键盘焦点，或者用户在元素上方点击了鼠标按钮。元素为它们支持的每一种事件都定义了一个事件属性，内联处理事件以on开头，比如onmouseover，可以直接在元素属性内定义。比如：&lt;p
			onmouseover="this.style.background='white';"&gt;。有些事件是单向的，在事件结束后并不会还原，比如onmousemover事件，要想还原需要定义与它配对的mouseout事件才能实现。最常用的是定义一个事件响应函数，在元素的事件定义中指向该函数，比如：onmouseover=handleMouseOver(elem)，在调时可使用this关键字指元素本身，比如:&lt;p
			onmouseover=handleMouseOver(this)&gt;。</p>

		<p>也可以使用DOM对象来应用事件，但是这样的脚本必须放在文档末尾，因为要处理的是所有元素。比如：</p>
		<pre>
			var pElements = document.getElementByTagName('p');
			for(var i=0; i< pElement.length; i++){
				pElement[i].onmouseover = handleMouseOver;	//注意此处没有参数
			}

			function handleMouseOver(e){		//注意，这里有个参数e，它会被设置为浏览器创建的一个Event对象，用于在事件触发时代表该事件。
				e.target.style.background='white';	//因为e是一个Event对象，代表触发事件，因此，这里用target属性来获取触发事件的HTMLElement
			}
		</pre>
		<p>还可以使用addEventListener()方法来添加事件（为函数和事件之间建立关联），比如pElement[i].addEventListener('mouseover',
			handleMouseOver);，也可以使用removeEventListener方法来取消函数与事件之间的关联。</p>

		<p>Event对象的函数和属性如下：</p>
		<ul>
			<li>type 事件的名称（比如mouseover)</li>
			<li>target 事件指向的元素，见上面的示例</li>
			<li>currentTarget 事件当前被触发事件监听器的元素</li>
			<li>eventPhase 事件生命周期的阶段</li>
			<li>bubbles 如果事件会在文档里冒泡则返回true，否则返回false</li>
			<li>cancelable 如果事件带有可撤销的默认行为则返回true，否则返回false</li>
			<li>timeStamp 事件的创建时间，如果时间不可用则为0</li>
			<li>stopPropagation() 在当前元素的事件监听器被触发后终止事件在元素树中的流动</li>
			<li>stopImmediatePropagation() 立即终止事件在元素树中的流动。当前元素上未被触发的事件监听器会被忽略</li>
			<li>preventDefault() 防止浏览器执行与事件关联的默认操作</li>
			<li>defaultPrevented 如果调用过preventDefault()则返回true</li>
		</ul>
		<p>type属性可以说明正在处理的事件类型，这样可以实现以一个函数来处理多个类型。比如function handleMouseEvent(e){ if(e.type ==
			'mouseover'){...}else{...}}。</p>

		<p>一个事件的生命周期包括三个阶段：捕捉、目标和冒泡。<a href="listing-09.html">事件冒泡示例在此</a>
			当某个事件被触发时，浏览器会找出事件涉及的元素，它被称为该事件的目标（target）。浏览器会找出body元素和目标之间的所有元素并分别检查他们（会从HTML的根节点起，沿着DOM向目标前进），年它们是否带有事件处理器且要求获得其后代元素触发事件的通知。浏览器会先触发这些事件处理器，然后才轮到目标自身的处理器。事件捕捉让目标元素的各个上级元素都有机会在事件传递到目标元素本身之前对其作出反应，而上级元素的事件处理器也可以阻止事件流向目标，方法是对Event对象调用stopPropagation（确保调用当前元素上注册的所有事件监听器）或stopImmediatePropagation（会忽略任何未触发的监听器）函数。Event.eventPhase属性有三个值来表示事件的阶段，如下：
		</p>
		<ul>
			<li>CAPTURING_PHASE 事件处于捕捉阶段</li>
			<li>AT_TARGET 事件处于目标阶段</li>
			<li>BUBBLING_PHASE 事件处于冒泡阶段</li>
		</ul>
		<p>
			当捕捉阶段完成后，浏览器会触发目标元素上任何已添加的事件类型监听器，需要注意的一点是可以多次调用addEventListener函数，因此某个给定事件类型可能有不止一个监听器。如果在这一阶段调用了stopPropagation或stopImmdiatePropagetion函数也会终止事件流，不再进入冒泡阶段。</p>

		<p>
			完成目标阶段后，浏览器开始转而沿着上级元素朝body元素前进。在沿途的每个元素上都会检查是否存在针对该事件类型但没有启用捕捉的监听器（也就是说addEventListener函数的第三个参数是false），这就是所谓的事件冒泡。</p>

		<p>
			有些事件定义了默认行为会在事件被触发时执行，比如a元素的click事件，它的默认行为是载入href指定的URL。当事件拥有默认行为时，它的cancelable属性就是true。可以使用preventDefault函数来阻止默认行为的执行。<a
				href="listing-10.html">可撤销事件示例在此</a></p>

		<p>HTML定义了一些按类型分组的事件。Document对象也有一个事件readystatechange它将在readyState属性的值发生变化时被触发。Window对象则定义了多种事件，如下：</p>
		<ul>
			<li>onabort 在文档或资源加载过程中被中止时触发</li>
			<li>onafterprint 在用户完成文档打印后触发</li>
			<li>onbeforeprint 在已调用Windows.print()方法，但尚未给用户提供打印选项时触发</li>
			<li>onerror 在文档或资源的加载发生错误时触发</li>
			<li>onhashchange 在锚部分发生变化时触发</li>
			<li>onload 在文档或资源加载完成时触发</li>
			<li>onpopstate 触发生提从一个关联浏览器历史的状态对象</li>
			<li>onresize 在窗口缩放时触发</li>
			<li>onunload 在文档从窗口或浏览器中卸载时触发</li>
		</ul>
		<p><a href="listing-11.html">鼠标事件示例在此</a> 下面是与鼠标相关的事件集合：</p>
		<ul>
			<li>click 在点击并释放鼠标按键时触发</li>
			<li>dbclick 在双击时触发</li>
			<li>mousedown 在按下时触发</li>
			<li>mouseenter 在光标移入元素或某个后代元素所占据的屏幕区域时触发</li>
			<li>mouseleave 在光标移出元素及所有后代元素所占据的屏幕区域时触发</li>
			<li>mousemove 当光标在元素上移动时触发</li>
			<li>mouseout 与mouseleave基本相同，除了当光标仍然在某个后代元素上时也会触发（在后代元素上不触发？）</li>
			<li>mouseover 与mouseenter基本相同，除了当光标仍然在某个后代元素上时也会触发</li>
			<li>mouseup 在释放鼠标时触发</li>
		</ul>
		<p>当某个鼠标事件被触发时，浏览器会指派一个MouseEvent对象，它是一个Event对象，但带有以下额外的属性和方法：</p>
		<ul>
			<li>button 标明点击的是鼠标的哪个键，0-主键（左），1-中键，2-次键（右）</li>
			<li>altKey 如果在事件触发时按下了alt/option键则返回true</li>
			<li>clientX 返回事件触发时鼠标相对于元素容器的X坐标</li>
			<li>clientY 返回事件触发时鼠标相对于元素容器的Y坐标</li>
			<li>screenX 返回事件触发时鼠标相对于屏幕坐标系的X坐标</li>
			<li>screenY 返回事件触发时鼠标相对于屏幕坐标系的Y坐标</li>
			<li>shiftKey 如果在事件触发时按下了shift键则返回true</li>
			<li>ctrlKey 如果在事件触发时按下了ctrl键则返回true</li>
		</ul>
		<p>与键盘焦点相关的事件触发于元素获得和失去焦点之时。这些事件如下：</p>
		<ul>
			<li>blur 在元素失去焦点时触发</li>
			<li>focus 在元素获得焦点时触发</li>
			<li>focusin 在元素即将获得焦点时触发</li>
			<li>foucsout 在元素即将失去焦点时触发</li>
		</ul>
		<p>
			FocusEvent对象代表了上述键盘事件，相对于Event对象的核心功能，它还增加了属性relatedTarget，这具属性只属于focusin和focusout，表示元素即将获得或失去焦点，它返回HTMLElement。<a
				href="listing-12.html">示例在此</a>。</p>

		<p>键盘事件由按键操作触发，有以下三个事件：keydown/keypress/keyup，分别表示用户按下/按下并释放/释放某个键时触发。<a href="listing-13.html">示例在此</a>。
			KeyboardEvent对象代表了这些事件，相对于Event对象的核心功能，它还增加了以下属性：</p>
		<ul>
			<li>char 返回按键代表的字符</li>
			<li>key 返回所按的键</li>
			<li>ctrlKey 如果在按键时同时按下Ctrl键则返回true</li>
			<li>shiftKey 如果在按键时同时按下shift键则返回true</li>
			<li>altKey 如果在按键时同时按下Alt键则返回true</li>
			<li>repeat 如果该键一直处于按下状态则返回true</li>
		</ul>
		<p>form元素定义了两种只适用于它的事件，一个是submit在提交时触发，一个是reset，在重置时触发。</p>
	</article>
	<article>
		<h1>第31章 使用元素专属对象</h1>

		<p>如果要访问某些元素特有的属性或功能，可以通过它们中的某个对象做到。比如表单元素有些方法可以进行输入验证，表格元素则可用于构建表格内容。</p>

		<p>
			base元素是由HTMLBaseElement对象代表，没有额外事件，只有两个属性：href和target。body元素由HTMLBodyElement对象代表，没有额外属性，只有一组事件：error（在脚本或图像等资源发生加载错误时触发）,load（在文档及它的所有资源加载完成时触发）,unload。</p>

		<p>这一章后面都是一些元素专属对象代表的列表，用处不是很大，用到时再查吧。</p>
	</article>
</section>
<section class="content">
	<h1>第五部分 高级功能</h1>

	<p>这些功能包括用于在后台向Web服务器发送请求的AJax和使用JavaScript进行绘图操作的canvas元素。</p>
	<article>
		<h1>第32章 使用Ajax（第I部分）</h1>

		<p>
			Ajax的关键在于XMLHttpRequest对象，浏览器异步执行并取回所请求的文档而主文档不会被重新加载，这就是Ajax。首先，需要创建一个XMLHttpRequest对象（比如httpRequest)，接下来为httpRequest.onreadystatechange创建一个方法（用来监听状态），然后为httpRequest指定HTTP方法（比如：GET或POST等），最后使用httpRequest.send()发送请求。</p>

		<p>
			一旦调用了send方法，浏览器就会在后台发送请求到服务器。因为请求是在后台处理的，所以Ajax依靠事件来通知请求的进展情况。当readystatechange事件被触发后，浏览器会把一个Event对象传给指定的处理函数，target属性则是与此事件关联的XMLHttpRequest，可以通过读取XMLHttpRequest.readyState属性的值来确定当前处理的是哪一个。下面是值列表：</p>
		<ul>
			<li>UNSENT 值为0，已创建XMLHttpRequest对象</li>
			<li>OPENED 值为1，已调用OPEN方法</li>
			<li>HEADERS_RECEIVED 值为2，已收到服务器响应的标头</li>
			<li>LOADING 值为3，已收到服务器响应</li>
			<li>DONE
				值为4，呼应完成或已失败，注意，它并不意味着成功，可以通过status属性获得HTTP状态码（状态码为200这个值时代表成功），因此综合使用readyState和status属性的值才能确定某个请求的结果。
			</li>
		</ul>
		<p>
			注意，在opera浏览器中有所不同，它在触发readystatechange事件时不会生成Event对象，因此，必须把XMLHttpRequest对象指派给一个全局变量。然后，它也没有上面的四个常量值，因此必须检查这四个值。（也许当前已有变化）</p>

		<p>除了readystatechange之外，还有一些其它事件可用，但是浏览器支持程序不一，最可靠的还是readystatechange：</p>
		<ul>
			<li>abort 在请求被中止时触发</li>
			<li>error 在请求失败触发</li>
			<li>load 在请求成功完成时触发</li>
			<li>loadend 在请求已完成时触发，无论成功还是发生错误</li>
			<li>loadstart 在请求开始时触发</li>
			<li>progress 触发以提示请求的进度</li>
			<li>readystatechange 在请求生命周期的不同阶段触发</li>
			<li>timeout 如果请求超时则触发</li>
		</ul>
		<p>调度以上事件时，浏览器会对readystatechange事件使用常规的Event对象，其它事件则使用ProgressEvent对象。ProgressEvent对象定义了Event对象的所有成员，并添加了以下成员(<a
				href="./xmlhttprequest.html">示例在此</a>）：</p>
		<ul>
			<li>lengthComputable 如果能够计算数据流的总长度则返回true</li>
			<li>loaded 返回当前已载入的数据量</li>
			<li>total 返回可用的数据总量</li>
		</ul>
		<p>
			使用Ajax时必须留心两类错误，它们之间的区别源于视角不同：第一类错误是从XMLHttpRequest对象的角度看到的问题-某些元素阻止了请𣷌发送到服务器，连接请求被拒绝或者URL无效；第二类问题是从应用程序的角度来看，它们发生于请求成功发送到服务器，服务器接受请求、进行处理并生成响应，但该响应并不指向你期望的内容时。<a
				href="ajaxerror.html">示例在此</a></p>

		<p>XMLHttpRequest对象可以设置发送给服务器的请求标头和读取服务器响应里的标头。与标头有关的方法如下：</p>
		<ul>
			<li>setRequestHeader(header, value) 用指定值设置标头</li>
			<li>getResponseHeader(header) 获取指定标头的值</li>
			<li>getAlResponseHeaders() 以单个字符串的形式获取所有标头</li>
		</ul>
		<p>除了GET和POST这两种HTTP协义支持的方法外，还有PUT和DELETE等。如果想删除数据可以发送httpRequest.open('DELETE',
			'http://myserver/freeman/adam')，这样可以直接用HTTP表达想要服务器做什么，但是许多主流技术只支持GET和POST（而且不少防火墙也只许这两种通过），有一种惯用做法可以规避这个限制，就是使用X-HTTP-Method-Override标头来指定想要命名用的HTTP方法，但在形式上是再发送一个POST请求，比如：httpRequest.setRequestHeader('X-HTTP-Method-Override',
			'DELETE');，注意，这个要放在httpRequest.open()方法之后使用。</p>

		<p>第二个可以添加到Ajax请求上的有用标头是Cache-Control，它可以让浏览器缓存通过Ajax请求所获得的内容。</p>

		<p>生成跨源的Ajax请求，这一节需要HTTP知识，使两个不同来源（不同站点，或同站不同端口）的文档可以通信。（暂且略过32.5小节）</p>

		<p></p>
	</article>
	<article>
		<h1>第33章 使用Ajax（第II部分）</h1>

		<p>发送表单和文件是Ajax的常见用途，它还可以监视向服务器发送数据的进度。</p>

		<p>因为用到了node.js，此处插入在Linux下安装node的方法：</p>
		<pre>
			git clone git://github.com/joyent/node.git
			cd node
			./configure
			make
			sudo make install
		</pre>
		<p>Linux的在线源里面也可以直接按装，还可以使用已编译好的文件。</p>

		<p>FormData是在XMLHttpRequest的第二级规范中定义，它可以实现收集表单数据。创建FormData对象时可以传递一个HTMLFormElement对象（即form元素），这样表单中所有元素的值都会被自动收集起来。比如：var formData = new FormData(formName);。FormData还可以手工添加名称/值对，只需要使用append(name,value)方法。</p>
		<p>Ajax几乎可用来发送任何东西，包括JavaScript对象表示法（JavaScript Object Notation, JSON）数据。要发送JSON数据需要先设置JSON标头告知服务器：httpRequest.setRequestHeader('Content-Type', 'application/json');。然后，将formData以JSON编码发送：httpRequest.send(JSON.stringify(formData));。</p>
		<p>上面用到的JSON对象有两个方法：parse(json) 解析用JSON编码的字符串并创建一个对象；stringify(object) 为指定对象创建JSON编码的数据表示。</p>
		<p>可以使用FormData对象和type属性为file的input元素向服务器发送文件。后面这一部分说得不详。还是再找node的书资料看吧。这本书就此结束。</p>
	</article>
	<article>
		<h1>第34章 使用多媒体</h1>

		<p>要在浏览器中使用多媒体，需要给Web服务器添加一些MIME类型。下面插入一个video元素，它是个流/短语元素，因此它嵌入在了这个段落当中。
			<video id="media" width="360" height="240" src="timessquare.webm" controls preload="metadata" muted>视频无法播放
			</video>
			，它的属性如下：
		</p>
		<ul>
			<li>autoplay 如果存在，会自动播放</li>
			<li>preload 告诉浏览器是否要预先载入视频，即在网页加载完后，是否主动下载视频，这可以减少用户播放时的延迟，它有三个值可用：
				<ul>
					<li>none 播放前不载入视频</li>
					<li>metadata 开始播放前只载入视频的元数据，比如：高度、宽度、第一帧、长度等等</li>
					<li>auto 请求浏览器尽快下载整个视频，浏览器也可以忽略，这是默认请求。</li>
				</ul>
			</li>
			<li>controls 显示播放控件</li>
			<li>loop 循环播放</li>
			<li>poster 指定视频数据载入时显示的图片，指定一张图片显示在video上，作为占位图像</li>
			<li>height/width 指定高/宽度，如果忽略，video会占很小空间，在开始播放时会调整到视频原始尺寸，因此，要设置这两个属性</li>
			<li>muted 静音</li>
			<li>src 视频文件URL</li>
		</ul>
		<p>当前HTML5支持的视频格式如下:</p>
		<ul>
			<li>WebM 由Google提供，但当前受到专利攻击，支持的浏览器有Opera,Chrome,Firefox</li>
			<li>Ogg/Theora 它是一种开放、免版税和无专利约束的格式，支持它的有Opera,Chrome和Firefox</li>
			<li>MP4/H.264 此格式当前可以免费使用到2015年，支持它的有IE,Chrome,Safari</li>
		</ul>
		<p>还可以使用source元素指定多个备选视频格式（支持哪个放哪个）比如像这样定义：</p>
		<pre>
			&lt;video controls width="360" height="240"&gt;
				&lt;source src="timessquare.webm" type="video/webm"&gt;
				&lt;source src="timesquare.ogv" type="video/ogg"&gt;
				&lt;source src="timessquare.mp4" type="video/mp4"&gt;
				视频无法播放
			&lt;/video&gt;
		</pre>
		<p>audio元素可以在文档里嵌入音频。它的用法类似于video，同样，也没有哪种格式获得全面支持。</p>

		<p>
			DOM用HTMLMediaElement对象为audio和video元素统一定义了核心功能。audio元素在DOM由HTMLAudioElement对象代表，没有定义不同于HTMLMediaElement的额外功能，而HTMLVideoElement对象代表video元素，它定义了额外的属性。</p>

		<p>HTMLMediaElement对象定义了许成员，用来获取和修改元素及其关联媒体的信息：</p>
		<ul>
			<li>autoplay 获取或设置autoplay属性</li>
			<li>canPlayType(type) 获取浏览器能否播放特定MIME类型的提示</li>
			<li>currentSrc 获取当前的媒体文件来源</li>
			<li>controls 获取或设置controls属性是否存在</li>
			<li>defaultMuted 获取或设置muted属性一开始是否存在</li>
			<li>loop/muted 获取或设置loop/muted属性是否存在</li>
			<li>prelaod/src 获取或设置preload/src属性的值</li>
			<li>volume 获取或设置音量，范围从0.0到1.0</li>
		</ul>
		<p>HTMLVideoElement对象定义的额外属性：</p>
		<ul>
			<li>height/width 获取或设置高/宽</li>
			<li>poster 获取或设置poster属性的值</li>
			<li>videoHeight/videoWidth 获取或设置视频的原始高度/宽度</li>
		</ul>
		<p>比如下面这段显示的视频元素信息，注意代码中的方式：</p>
		<table id="info" border="1">
			<tr>
				<th>Property</th>
				<th>Value</th>
			</tr>
		</table>
		<script>
			var mediaElement = document.getElementById('media');
			var tableElement = document.getElementById('info');

			var propertyName = ['autoplay', 'currentSrc', 'controls', 'loop', 'muted', 'preload', 'src', 'volume'];

			for (var i = 0; i < propertyName.length; i++) {
				tableElement.innerHTML += '<tr><td>' + propertyName[i] + '</td><td>' + mediaElement[propertyName[i]] + '</td></tr>';
			}
		</script>
		<p>canPlayType()方法可以了解浏览器是否能播放特定的媒体格式，它可以返回三个值：'' 空，无法播放；maybe 也许可以播放；probably 有把握可以播放。</p>

		<p>HTMLMediaElement对象定义了许多成员，实现回放控制和获得回放信息，这些方法和属性如下：</p>
		<ul>
			<li>currentTime 返回媒体文件当前的回放点</li>
			<li>duration 返回媒体文件的总时长</li>
			<li>ended 如果媒体文件已播放完毕则返回true</li>
			<li>pause() 暂停</li>
			<li>paused 如果回放暂停就返回true，否则，返回false</li>
			<li>play() 开始回放媒体</li>
		</ul>
	</article>
	<article>
		<h1>第35章 使用canvas元素（第I部分）</h1>

		<p>canvas元素是一种可供绘图的平面，用JavaScript对它进行配置和操作。canvas元素本身很简音，只有两个属性（height和width)，它的所有功能都体现在JavaScript对象上。</p>

		<p>
			要在canvas元素上绘图，需要获得一个上下文对象，它会开放针对特定图形样式的绘图函数。HTMLCanvasElement对象有三个属性：width/height/getContext(context)为画布返回绘图上下文。</p>

		<p>
			简单的图形绘制方法：clearRect(x,y,w,h)清除指定的矩形；fillRect(x,y,w,h)绘制实心矩形；strokeRect(x,y,w,h)绘制空心矩形。xy表示左上角坐标，wh指待绘矩形的宽和高。</p>
		<style>
			canvas {
				border: medium double #000000;
				margin: 4px;
			}
		</style>
		<canvas id="canvas" width="500" height="140">你的浏览器不支持canvas元素。</canvas>
		<script>
			var ctx = document.getElementById('canvas').getContext('2d');


			var grad = ctx.createLinearGradient(0, 0, 500, 140);
			grad.addColorStop(0, 'red');
			grad.addColorStop(0.5, 'white');
			grad.addColorStop(1, 'blue');

			ctx.fillStyle = grad;
			ctx.fillRect(0, 0, 500, 140);

			ctx.lineJoin = 'round';
			ctx.lineWidth = 2;
			var grad = ctx.createLinearGradient(10, 10, 50, 50);
			grad.addColorStop(0, 'red');
			grad.addColorStop(0.5, 'white');
			grad.addColorStop(1, 'blue');
			ctx.fillStyle = grad;
			ctx.fillRect(10, 10, 50, 50);
			ctx.strokeRect(80, 10, 50, 50);

			var grad = ctx.createRadialGradient(250, 70, 20, 200, 60, 100);
			grad.addColorStop(0, 'red');
			grad.addColorStop(0.5, 'white');
			grad.addColorStop(1, 'yellow');

			ctx.fillStyle = grad;
			ctx.fillRect(0, 0, 500, 140);
		</script>
		<p>绘图操作由绘制状态加以配置，它是一组属性，指定了从线条宽度到填充色的所有参数。绘制状态的属基本属性如下：</p>
		<ul>
			<li>fillStyle 获取或设置用于实心图形的样式</li>
			<li>lineJoin 获取或设置线条与图形连接时的样式</li>
			<li>lineWidth 获取或设置线条的宽度</li>
			<li>strokeStyle 获取或设置用于线条的样式</li>
		</ul>
		<p>
			还可以把填充和笔触样式设置为渐变化，canvas元素支持两类渐变：createLinearGradient(x0,y0,x1,y1)创建线性渐变;createRadialGradient(x0,y0,r0,x1,y1,r1)创建径向渐变（x0y0起点圆圆心，r0起点圆半径，x1y1终点圆圆心，r1终点圆半径），两个方法都返回一个CanvasGradient对象，此对象有以下方法：addColorStop(position,
			color) 给渐变的梯度添加一种纯色。</p>

		<p>径向渐变的定义是由两个圆决定的，渐变的起点由第一个圆定义，终点则是第二个圆，在两者之间添加颜色点。注意，不同浏览器对于不存在包含关系的两个圆实现渐变的方式可以不一样。</p>

		<p>
			对画布上下文使用createPattern方法可以创建图案（本来设计三种方式，图像、视频和画布）填充，当前只有图像在Firefox和Opera中得到支持。要用图像填充，城要将一个HTMLImageElement对象作为第一个参数传递给createPattern方法，第二个参数定义的是重复样式（repeat/repeat-x/repeat-y/no-repeat)。要实现图像填充可以这样做：</p>
		<ol>
			<li>定义canvas元素</li>
			<li>定义img元素，并设置它的hidden属性</li>
			<li>JavaScript脚本
				<ol>
					<li>取得上下文 比如var ctx = document.getElementById('canvas').getContext('2d');</li>
					<li>创建HTMLImageElement对象，比如var imageElement = document.getElementById('banana');</li>
					<li>添充图像到canvas，比如var pattern = ctx.crfeatePattern(imageElement, 'repeat');</li>
					<li>绘制：ctx.fillStyle=pattern; ctx.fillRect(0,0,500,140);</li>
				</ol>
			</li>
		</ol>
		<p>可以保存（save()）和恢复（restore()）绘制状态属性的值。</p>

		<p>可以使用drawImage方法在画布上绘制图像，它可以有三个、五个或九个参数，第一个参数始终是图像来源，下面是其它的八个参数：</p>
		<ol>
			<li>第二三个参数昌在源图像内的偏移量</li>
			<li>第四五个参数是源图像所需使用区域的宽度和高度</li>
			<li>第六七个参数指定了所选区域左上角将要在画布上绘制的坐标</li>
			<li>第八九个参数指定了所选区域将要绘制的宽度和高度</li>
		</ol>
		<p>也可以使用video元素作为drawImage方示的图像来源，这么做实际是对视频做了截图。<a href="listing-18-1.html">示例在此</a></p>

		<p>还可以将一张画布的内容，作为另一张里drawImage方法的来源。</p>
	</article>
	<article>
		<h1>第36章 使用canvas元素（第II部分）</h1>

		<p>用路径绘图，所谓路径本质上就是一组独立的线条（称为子路径），它们组合在一起构成图形。绘制子路径的方式就像用笔在纸上画图一样，笔尖不离开纸面，每一条子路径都以上一条的终点作为起点。基本的路径方法如下：</p>
		<ul>
			<li>beginPath() 开始一条新路径</li>
			<li>closePath() 尝试闭合现有路径，方法是用直线连接终点与初始坐标</li>
			<li>fill() 填弃子路径描述的图形</li>
			<li>isPointInPath(x,y) 如果指定的点在当前路径所描述的图形之内则返回true</li>
			<li>lineTo(x,y) 绘制一条到指定坐标的子路径</li>
			<li>moveTo(x,y) 移动到指定坐标而不绘制子路径</li>
			<li>rect(x,y,w,h) 绘制一个矩形，左上角位于x,y，宽度是w高度是h，如果只是绘制单独的矩形用fillRect或strokeRect就足够了，但是如果要给更复杂的图形添加矩形的话，就用这个。</li>
			<li>stroke() 给子路径描述的图形绘制轮廓线</li>
		</ul>
		<p>绘制一条路径的基本顺序如下：</p>
		<ol>
			<li>调用beginPath方法</li>
			<li>用moveTo方法移动到起点</li>
			<li>用arc和lineTo等方法绘制子路径</li>
			<li>调用closePath方法（可选）</li>
			<li>调用fill或stroke方法</li>
		</ol>
		<p>可以用lineCap属性来设置线条末端的样式，它有三个值：butt(默认）、round和square，当然要足够宽才能显示，而且round和square样式会超出末端边缘。</p>
		<canvas id="draw" width="500" height="140">你的浏览器不支持canvas标记</canvas>
		<script>
			var ctx = document.getElementById('draw').getContext('2d');

			ctx.fillStyle = 'yellow';
			ctx.strokeStyle = 'blue';
			ctx.lineWidth = 4;

			ctx.beginPath();
			ctx.moveTo(10,10);
			ctx.lineTo(110,10);
			ctx.lineTo(110,120);
			ctx.closePath();
			ctx.fill();		//填充

			ctx.beginPath();
			ctx.moveTo(150,10);
			ctx.lineTo(200,10);
			ctx.lineTo(200,120);
			ctx.lineTo(190,120);
			ctx.fill();
			ctx.stroke();	//绘制轮廓

			ctx.beginPath();
			ctx.moveTo(250,10);
			ctx.lineTo(250,120);
			ctx.stroke();

			ctx.lineWidth = 1;
			ctx.beginPath();
			ctx.moveTo(0,50);
			ctx.lineTo(500,50);
			ctx.stroke();

			var xpos = 50;
			ctx.lineWidth = 40;
			var styles = ['butt', 'round', 'square'];

			for(var i = 0; i < styles.length; i++){
				ctx.beginPath();
				ctx.lineCap = styles[i];
				ctx.moveTo(xpos + 250, 50);
				ctx.lineTo(xpos + 250, 150);
				ctx.stroke();
				xpos += 50;
			}

		</script>
		<p>下面用rect来绘矩形</p>
		<canvas id="rect" width="500" height="140">你的浏览器不支持canvas标记</canvas>
		<script>
			var ctx = document.getElementById('rect').getContext('2d');

			ctx.fillStyle = 'yellow';
			ctx.strokeStyle = 'blue';
			ctx.lineWidth = 4;

			ctx.beginPath();
			ctx.moveTo(110, 10);
			ctx.lineTo(110, 100);
			ctx.lineTo(10, 10);
			ctx.closePath();

			ctx.rect(120, 10, 100, 90);
			ctx.rect(120, 110, 100, 90);
			ctx.fill();
			ctx.stroke();
		</script>
		<p>使用arc和arcTo方法可以绘制圆弧，不过它们的方式有所不同：</p>
		<ul>
			<li>arc(x,y,rad,startAngle, endAngle, direction) 绘制一段圆弧到(x,y)，半径为rad，起始角度为startAngle，结束角度为endAngle。可选参数direction指定了圆弧的方向。</li>
			<li>arcTo(x1,y1,x2,y2,rad) 绘制一个半径为rad，经过起点(x1,y1)直到终点(x2,y2)的圆弧，canvas会在起点和终点间画一条半径为rad的最短圆弧。</li>
		</ul>
		<p>下面这个示例可以响应鼠标移动来绘制圆弧</p>
		<canvas id="arc" width="500" height="140">浏览器不支持Canvas</canvas>
		<script>
			var canvasElement = document.getElementById('arc');
			var ctx = canvasElement.getContext('2d');

			var point1 = [100, 10];
			var point2 = [200, 10];
			var point3 = [200, 110];

			draw();

			//这个函数的坐标是相对于浏览器的，因此，和Canvas中的实际坐标不一致
			canvasElement.onmousemove = function(e){
				if(e.ctrlKey){
					point1 = [e.clientX, e.clientY];
				}else if(e.shiftKey) {
					point2 = [e.clientX, e.clientY];
				}else{
					point3 = [e.clientX, e.clientY];
				}

				ctx.clearRect(0, 0, 540, 140);
				draw();
			}

			function draw(){
				ctx.fillStyle = 'yellow';
				ctx.strokeStyle = 'blue';
				ctx.lineWidth = 4;

				ctx.beginPath();
				ctx.moveTo(point1[0], point1[1]);
				ctx.arcTo(point2[0], point2[1], point3[0], point3[1], 100);
				ctx.stroke();

				drawPoint(point1[0], point1[1]);
				drawPoint(point2[0], point2[1]);
				drawPoint(point3[0], point3[1]);

				ctx.beginPath();
				ctx.moveTo(point1[0], point1[1]);
				ctx.lineTo(point2[0], point2[1]);
				ctx.lineTo(point3[0], point3[1]);
				ctx.stroke();
			}

			function drawPoint(x, y){
				ctx.lineWidth = 1;
				ctx.strokeStyle = 'red';
				ctx.strokeRect(x - 2, y - 2, 4, 4);
			}
		</script>
		<p>canvas支持绘制两种贝塞尔曲线：三次和两次。由于得不到任何视觉反馋馆馈，因此难以获得想要的曲线。两种方法分别如下：</p>
		<ul>
			<li>bezierCurveTo(cx1,cy1,cx2,cy2,x,y) 绘制一段贝塞尔曲到到(x,y)，控制点为(cx1,cy1)和(cx2,cy2)</li>
			<li>quadraticCurveTo(cx,cy,x,y) 绘制一段二次贝塞尔曲线到点(x,y)，控制点为(cx,cy)</li>
		</ul>
		<p>两次贝塞尔曲线的示例如下(按下shift建移动鼠标试下，注意，坐标系的问题导致鼠标与画布上的点不一致）：</p>
		<canvas id="quadratic" width="500" height="140">浏览器不支持canvas</canvas>
		<script>
			var canvasElement = document.getElementById('quadratic');
			var ctx = canvasElement.getContext('2d');

			//下面设置阴影
			ctx.shadowOffsetX = 5;
			ctx.shadowOffsetY = 5;
			ctx.shadowBlur = 5;
			ctx.shadowColor = 'red';

			ctx.font = '100px 宋体';	//注意，字体不能省
			ctx.textBaseline = 'top';
			ctx.strokeText('这是一个二次贝塞尔曲线的示例', 50,100);
			var startPoint = [50, 100];
			var endPoint = [400, 100];
			var cp1 = [250, 50];

			canvasElement.onmousemove = function (e) {
				if(e.shiftKey){
					cp1 = [e.clientX, e.clientY];
				}
				ctx.clearRect(0, 0, 500, 140);
				drawQuadratic();
			}

			drawQuadratic();

			function drawQuadratic(){
				ctx.lineWidth = 3;
				ctx.strokeStyle = 'blue';
				ctx.beginPath();
				ctx.moveTo(startPoint[0], startPoint[1]);
				ctx.quadraticCurveTo(cp1[0], cp1[1], endPoint[0], endPoint[1]);
				ctx.stroke();

				ctx.lineWidth = 1;
				ctx.strokeStyle = 'red';
				var points = [startPoint,endPoint, cp1];
				for(var i = 0; i < points.length; i++) {
					drawPoints(points[i]);
				}

				drawLine(startPoint, cp1);
				drawLine(endPoint, cp1);
			}

			function drawPoints(point){
				ctx.beginPath();
				ctx.strokeRect(point[0] - 2, point[1] - 2, 4, 4);
			}

			function drawLine(from, to){
				ctx.beginPath();
				ctx.moveTo(from[0], from[1]);
				ctx.lineTo(to[0], to[1]);
				ctx.stroke();
			}
		</script>
		<p>可以使用clip方法来创建裁剪区域，这样，只有区域范围内的路径才会显示出来。要创建它，只需要创建形状的路径后紧跟clip()方法即可：比如ctx.beginPath();ctx.rect(100,20,100,50);ctx.clip();。</p>
		<p>可以在canvas画布上绘制文本，虽然功能比较简陋。</p>
		<ul>
			<li>fillText(text, x, y, width) 在位置（x,y）上绘制并填充指定文本，宽度是可选的，它设置的是文本宽度的上限</li>
			<li>strokeText(text, x, y, width) 在位置（x,y）上绘制并描边指定文本，其余同上</li>
		</ul>
		<p>可以使用三种绘制状态属性来控制文本绘制：</p>
		<ul>
			<li>font 设置字体大小和小式，比如:ctx.font='50px sans-serif'，注意，字体参数不能省</li>
			<li>textAlign 对齐方式：start/end/left/right/center</li>
			<li>textBaseline 设置文本的基线：top/hanging/middle(默认）/alphabetic/ideographic/bottom</li>
		</ul>
		<p>有四种属性可以给绘制的图形和文本添加阴影：</p>
		<ul>
			<li>shadowBlur 设置阴影的模糊程度</li>
			<li>shadowColor 设置阴影的颜色</li>
			<li>shadowOffsetX 设置阴影的水平偏移量</li>
			<li>shadowOffsetY 设置阴影的垂直偏移量</li>
		</ul>
		<p>有两种方式来为文本和图形设置透明度，第一种是用rgba函数指定一个fillStyle或strokeStyle值，第二种是使用绘制状态属性globalAlpha，它应用的透明度是全局性的，比如：ctx.globalAlpha = 0.5;。</p>
		<p>可以将透明度与globalCompositeOperation属性结合使用来控制图形和文本在画布上绘制的方式，这个属性可以创建一些引人注目的效果，它允许使用以下值：</p>
		<ul>
			<li>copy 将来源绘制于目标之上，忽略一切透明度设置</li>
			<li>destination-atop 与source-atop相同，但用目标图像替代来源图像，反之亦然</li>
			<li>destination-in 与source-in相同，但用目标图像替代来源图像，反之亦然</li>
			<li>destination-over 与source-over相同，但用目标图像替代来源图像，反之亦然</li>
			<li>destination-out 与source-out相同，但用目标图像替代来源图像，反之亦然</li>
			<li>lighter 显示来源图像与目标图像的总和，颜色值限制最高255（100%）</li>
			<li>source-atop 在两个图像都不透明处显示来源图像。目标图像不透明但来源图像透明处显示目标图像，其他位置显示为透明。</li>
			<li>source-in 来源图像和目标图像都不透明处显示来源图像，其它位置显示为透明</li>
			<li>source-out 来源图像不透明但目标图像透明处显示来源图像。其他位置显示为透明</li>
			<li>source-over 来源图像不透明处显示来源图像。其他位置显示目标图像</li>
			<li>xor 对来源图像和目标图像执行异或运算</li>
		</ul>
		<p>好像只用source的值就够用了，下面是示例：</p>
		<canvas id="composite" width="300" height="100">不支持</canvas>
		<label>Composition value:</label>
		<select id="list">
			<option>copy</option>
			<option>destination-atop</option>
			<option>destination-in</option>
			<option>destination-over</option>
			<option>destination-out</option>
			<option>lighter</option>
			<option>source-atop</option>
			<option>source-in</option>
			<option>source-out</option>
			<option>source-over</option>
			<option>xor</option>
		</select>
		<script>
			var ctx = document.getElementById('composite').getContext('2d');

			ctx.fillStyle = 'lightgrey';
			ctx.strokeStyle = 'black';
			ctx.lineWidth = 3;

			var compVal = 'copy';
			document.getElementById('list').onchange = function(e){
				compVal = e.target.value;
				drawComp();
			}

			drawComp();

			function drawComp(){
				ctx.clearRect(0,0,300,100);
				ctx.globalAlpha = 1.0;
				ctx.font = '100px sans-serif';
				ctx.fillText('Hello', 10, 100);
				ctx.strokeText('Hello', 10,100);

				ctx.globalCompositeOperation = compVal;

				ctx.fillStyle = 'red';
				ctx.globalAlpha = 0.5;
				ctx.fillRect(100, 10, 150,100);
			}
		</script>
		<p>还可以使用变形，可用属性如下：</p>
		<ul>
			<li>scale(xScale, yScale) 沿X轴缩放画布xScale倍，沿Y轴yScale倍</li>
			<li>rotate(angle) 使画布围绕点(0,0)顺时针旋转指定的弧度数</li>
			<li>translate(x,y) 重映射画布坐标为沿X轴x，沿Y轴y</li>
			<li>transform(a,b,c,d,e,f) 合并现有的变换和a-f值所指定的矩阵（就这后面的两个不明白，还没有示例）</li>
			<li>setTransform(a,b,c,d,e,f) 用a-f值所指定的矩阵替换现有的变换</li>
		</ul>
	</article>
	<article>
		<h1>第37章 使用拖放</h1>
		<p>施放还处于起步阶段，实现与规范之间有很大不同。通过draggable属性告诉浏览器文档中的哪些元素可被拖动，它有三个值：true/false/auto(由浏览器自主决定某个元素是否能被拖动，默认值）。</p>
		<p>通过事件来利用拖动功能，被拖动元素的可用事件有以下三个：</p>
		<ul>
			<li>dragstart 在元素开始被拖动时触发</li>
			<li>drag 在元素被拖动时触发</li>
			<li>dragend 在拖动操作完成时触发</li>
		</ul>
		<p>要让某个元素成为释放区，需要处理dragenter和dragover事件，下面是完整的释放区事件列表：</p>
		<ul>
			<li>dragenter 当被拖动元素进入释放区所战友据的屏幕空间时被触发</li>
			<li>dragover 当被拖动元素在释放区内移动时被触发</li>
			<li>dragleave 当被拖动元素没有放下就离开释放区时触发</li>
			<li>drop 当被拖动元素在释放区里放下时触发</li>
		</ul>
		<p>规范要求释放区应定义dropzone属性，但实际上浏览器并不是这样实现的。要接收释放需要处理drop事件。<a href="listing-04.html">示例在此</a> </p>
		<p>与拖放操作事件同时派发的对象是DragEvent，它派生于MouseEvent，它定义了Event和MouseEvent对象的所有功能，并额外增加了如属性dataTransfer（返回用于传输数据到释放区的对象DataTransfer）。可以用DataTransfer对象从被拖动元素传输任意数据到释放区元素上，使用这种方式的好处是，它可以在不同（类型）浏览器间传递数据（因为拖放功能的支持是集成进操作系统的），它的属性和方法如下：</p>
		<ul>
			<li>types 返回数据的格式</li>
			<li>getData(format) 返回指定格式的数据，可以像这样判断拖动内容并采取相应操作：if(e.dataTransfer.getData('Text') == 'banana')，但是这个方法在chrome中无效</li>
			<li>setData(format,data) 设置指定格式的数据，第一个参数是数据类型，现在只有两种类型（Text和Url）得到了很好的支持，第二个参数是数据内容</li>
			<li>clearData(format) 移除指定格式的数据</li>
			<li>files 返回已被拖动文件的列表（FileList）</li>
		</ul>
		<p>还可以用DataTransfer实现文件的拖放，当文件放入释放区时会产生一个FileList对象（可看作是由File对象构成的数组，每个对象都代表一个文件），File对象定义的属性如下：</p>
		<ul>
			<li>name 获取文件名</li>
			<li>type 获取文件类型</li>
			<li>size 获取文件大小</li>
		</ul>
		<p>可以结合拖放功能、文件API和Ajax请求上传数据<a href="listing-07-1.html">示例在此，但没有包含上传功能</a>。事实上，可以用JavaScript库比如jQuery和jQuery UI实现完成的功能。</p>
	</article>
	<article>
		<h1>第38章 使用地理定位</h1>
		<p>地理定位不是HTML5规范的一部分。可通过全局属性navigator.geolocation访问地理定位功能，它返回一个Geolocation对象，这个对象有如下方法：</p>
		<ul>
			<li>getCurrentPosition(callback, errorCallback, options) 获取当前位置，但位置信息不是由函数自身返回的，它会传递一个Position对象给回调函数，在位置信息可用时被触发。Position对象很简单，就两个属性如下：
				<ul>
					<li>coords 以Coordinates对象返回当前位置的坐标，Coordinates对象的属性如下：
						<ul>
							<li>latitude 返回十进制纬度</li>
							<li>longitude 反回十进制经度</li>
							<li>altitude 返回以米表示的海拔</li>
							<li>accuracy 返回以米表示的坐标精度</li>
							<li>altitudeAccuracy 返回以米表示的海拔精度</li>
							<li>heading 返回用度表示的行进方向</li>
							<li>speed 返回用米/秒表示的行进速度</li>
						</ul>
						第二个参数也是个回调函数，它会在发生错误时获得一个PositionError对象，此对象就两个属性：code错误代码（有三个值-1用户未授权；2不能确定位置；3请求位置尝试超时），message描述错误的字符串。
						第三个参数是PositionOptions对象，它允许我们控制位置信息的获取方式：
						<ul>
							<li>enableHighAccuracy 告诉浏览器希望得到可能的最佳结果（只是请求，并不能保证）</li>
							<li>timeout 限制请求位置的时间，设置多少毫秒后报告超时错误</li>
							<li>maximumAge 告诉浏览器我们愿意接受缓存过的位置，只要它不早于指定的毫秒数</li>
						</ul>
						<a href="listing-03.html">示例在此</a>注意，里面没有使用PositionOptions对象，而是用一个定义了PositionOptions对象属性的Object对象代替了，说明这样也是可以的。
					</li>
					<li>timestamp 返回获取坐标信息的时间</li>
				</ul>
			</li>
			<li>watchPosition(callback, error, options) 开始监控当前位置，它将返回一个id，可用于停止监控。它不断获得位置的更新参数和工作方式也与getCurrentPosition相同，区别在于，随着位置变化，这个方法的回调函数会被反复调用，即不停地更新位置。如果要停止监控，只要把这个方法返回的ID值传递给clearWatch方法即可。</li>
			<li>clearWatch(id) 停止监控当前位置</li>
		</ul>
	</article>
	<article>
		<h1>第39章 使用Web存储</h1>
		<p>Web存储与cookie很相似，也是在浏览器中保存简单的键/值数据，但它有更好的实现方式，保存的数据量也更大。</p>
		<p>可以通过全局对象localStorage（不需要定义，直接使用）访问本地存储功能，它返回一个Storage对象以保存键/值形式的字符中对。<a href="listing-01.html">示例在此</a> Storage对象的属性和方法如下：</p>
		<ul>
			<li>clear() 移除保存的键/值对</li>
			<li>getItem(key) 取得与指定键关联的值</li>
			<li>key(index) 取得指定索引的键</li>
			<li>length 返回已保存的键/值对数量</li>
			<li>removeItem(key) 移除指定键对应的键/值对</li>
			<li>setItem(key, value) 添加一个新的键/值对，如果键名已存在则更新其值，因为键必须是唯一的</li>
			<li>[key] 用数组的访问形式取得与指定键关联的值</li>
		</ul>
		<p>这些键/值对在文档关闭后仍然存在，直接浏览器被关才消失。某个文档对本地存储进行修改时会触发storage事件，可以通过监听其他同源文档上的这个事件来确保得到最新变化。与storage事件同时指派的对象是StorageEvent对象，它的成员如下：</p>
		<ul>
			<li>key 返回发生变化的键</li>
			<li>oldValue 返回此键的旧值</li>
			<li>newValue 返回此键的新值</li>
			<li>url 返回制造变化的文档URL</li>
			<li>storageArea 返回发生变化的Storage对象</li>
		</ul>
		<p>storage事件是通过Window对象触发的（可以如下使用windows.onstorage = handleStorage)，它可以来自被改动存储的任何一个文档。<a href="listing-02.html">示例</a>运行不成功，估计没有得到全面支持。</p>
		<p>会话存储的工作方式和本地存储很接近，不同之处在于数据是各个浏览上下文私有的，在文档半闭时即被移除。可以通过sessionStorage访问会话存储，它会返回一个Storage对象。会话存储的storge事件只会在内嵌文档（比如iframe）中触发。</p>
	</article>
	<article>
		<h1>第40章 创建离线Web应用程序</h1>
		<p>创建离线应用程序的目标是确保所有需要的资源在离线状态下可以使用，它而让应用程序正常工作。清单文件可以帮我们实现这个目标，离线应用程序的规范建议把HTML文档本身也加入清单中，虽然当清单被载入和读取时文档已在浏览器缓存中了。</p>
		<p>清单文件没有固定命名方案，最常用的是.appcache为扩展名，比如水果图片放在fruit.appcache清单文件中。无论有哪种类型的命名方式，都必须让Web服务器把里面的内容向浏览器描述为MIME类型text/cache-manifest。通过html元素的manifest属性来定义关联的清单文档，而清单文档的内容就是可以离线使用的文件名列表，不需要定义路径只用文件名即可，一个文件名占一行。比如：</p>
		<pre>
		CACHE MANIFEST

		CACHE:
		example.html
		banana100.png
		cherries100.png
		apple100.png

		FALLBACK:
		* offline2.html

		NETWORK:
		cherries100.png
		</pre>
		<p>清单区域共有三种：</p>
		<ol>
			<li>缓存区域 可以把要缓存的文件直接列在清单文件的开头，也可以清单文件中创建CACHE区域，如上例中的CACHE:下面的部分</li>
			<li>备用区域 FALLBACK区域允许我们指定浏览器应当如何处理没有包括在清单内的资源。上例中说胆如果要需要未被离线缓存的png文件就用offine.html文件代替</li>
			<li>网络区域 NETWORK区域则用来定义不可被缓存的资源。在其后的资源意味着必须从服务器请求，不管在线还是离线。</li>
		</ol>
		<p>可以通过window.navigator.onLine属性判断浏览器是在线（true）还是离线（false）。</p>
		<p>可以通过调用window.applicationCache属性直接使用离线缓存，它返回一个ApplicationCache对象，它的成员如下：</p>
		<ul>
			<li>update() 更新缓存以确保清单里的项目都已下载了最新的版本</li>
			<li>swapCache() 交换当前缓存与较新缓存</li>
			<li>status 返回缓存状态，它会返回一个数值，对应集合如下：
				<ul>
					<li>0 UNCACHED 此文档没有缓存或缓存数据尚未下载</li>
					<li>1 IDLE 缓存没有执行任何操作</li>
					<li>2 CHECKING 浏览器正在检查清单或清单所指定项目的更新</li>
					<li>3 DOWNLOADING 正在下载清单或内容的更新</li>
					<li>4 UPDATEREADY 有更新后的缓存数据可用</li>
					<li>5 OBSOLETE 缓存数据已废弃，不应该再使用了。这是请求清单文件时返回HTTP状态码4XX所造成的（表明清单文件已不存在）</li>
				</ul>
			</li>
		</ul>
		<p>除此之外，ApplicationCache对象还定义了一组事件，它们会在缓存状态改变时被触发(<a href="listing-11-1.html">示例</a>）：</p>
		<ul>
			<li>checking 正在获取初始清单或检查清单更新</li>
			<li>noupdate 没有更新可用</li>
			<li>downloading 下在下载清单指定的内容</li>
			<li>progress 在下载阶段触发</li>
			<li>cached 清单里指定的所有内容都已被下载和缓存了</li>
			<li>updateready 新资源已下载并且可以使用了</li>
			<li>obsolete 缓存已废弃</li>
		</ul>
		<p>在清单文件的列表中的文件内容发生改变时，浏览器是不会自动下载更新的。最安全的做法是设置Web服务器，让它把Cache-Control标头设为no-cache。使用ApplicationChace对象的update方法时，它只是检查清单文件内容有没有变化（而不是文件列表所指的文件内容）有就更新，没有则不更新。另外，更新后和到实际应用之间还有会不定时的延时（这叫毛事？！）</p>
		<p>测试和调试应用程序缓存是个令人抓狂的过程，特别是通过ApplicationCache对象直接掌控缓存情况。</p>

	</article>
</section>
</body>
</html>